package com.yanqu.road.server.manager.activity.seacraftsouthsea;

import com.alibaba.fastjson.JSON;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.CrossActivityDetail;
import com.yanqu.road.entity.activity.seacraft.*;
import com.yanqu.road.entity.activity.seacraft.config.SeacraftSouthSeaActivityConfig;
import com.yanqu.road.entity.activity.seacraft.config.SeacraftSouthSeaFloorConfig;
import com.yanqu.road.entity.activity.seacraft.config.SeacraftSouthSeaShipConfig;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.config.goods.OpenGoodsBagResult;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.log.LogSeacraftSouthSeaDonation;
import com.yanqu.road.entity.log.LogSeacraftSouthSeaGuess;
import com.yanqu.road.entity.log.LogSeacraftSouthSeaRoundShip;
import com.yanqu.road.entity.log.LogSeacraftSouthSeaTeam;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.yrank.UserYRank;
import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.entity.union.honors.eHonorsActivityType;
import com.yanqu.road.logic.bussiness.activity.SeacraftSouthSeaBusiness;
import com.yanqu.road.logic.cross.CrossActivityRankListModel;
import com.yanqu.road.logic.helper.RandomWeightConfigHelper;
import com.yanqu.road.logic.helper.UnionHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.pb.activity.SeacraftSouthSeaProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.manager.activity.ActivityRankMgr;
import com.yanqu.road.server.manager.config.GoodsMgr;
import com.yanqu.road.server.manager.config.PatronsMgr;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.manager.union.honors.CrossUnionHonorsActivityMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manager.yrank.CrossYRankCacheMgr;
import com.yanqu.road.server.manager.yrank.CrossYRankMgr;
import com.yanqu.road.server.manger.SeacraftSouthSeaCommonMgr;
import com.yanqu.road.server.manger.TempGoodsBagMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.mina.util.ConcurrentHashSet;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @Description 海上争霸之南海丝路
 * @Author cwq
 * @Data 2022/1/20 15:44
 */
public class SeacraftSouthSeaActivity {

    private static Logger logger = LogManager.getLogger(SeacraftSouthSeaActivity.class.getName());

    private int activityId;
    private int groupId;

    /**
     * 参与的联盟信息
     */
    private Map<String, SeacraftSouthSeaUnionInfo> unionInfoMap = new ConcurrentHashMap<>();

    /**
     * 玩家数据
     */
    private Map<Long, SeacraftSouthSeaCrossUserInfo> userInfoMap = new ConcurrentHashMap<>();

    /**
     * 排行榜
     */
    private List<SeacraftSouthSeaUnionInfo> rankList = new CopyOnWriteArrayList<>();

    /**
     * 每轮的晋级数据 k:roundId 1 2 3, v:晋级联盟集合   备注 海盗之乱 k = 1 ,南海丝路第一轮 k=2
     */
    private Map<Integer, List<String>> promotionMap = new ConcurrentHashMap<>();

    /**
     * 竞猜数据 k:roundId, k:晋级联盟 v: 竞猜的数量
     */
    private Map<Integer, Map<String, Integer>> guessMap = new ConcurrentHashMap<>();

    /**
     * 竞猜数据 k:roundId 南海丝路轮次, k:猜中的档位 v:猜中的玩家集合
     */
    private Map<Integer, Map<Integer, List<Long>>> guessTimesMap = new ConcurrentHashMap<>();

    /**
     * 在南海丝路 系统里面的玩家
     */
    public Set<Long> inActivitySet = new ConcurrentHashSet<>();

    /**
     * 最新的跑马灯
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaMarqueeInfo.Builder lastMarqueeInfo = null;

    /**
     * 海盗之乱 晋级的联盟数据是否 全部同步了
     */
    public AtomicBoolean isSyn = new AtomicBoolean(false);

    @Deprecated
    public SeacraftSouthSeaActivity(int activityId) {
        this.activityId = activityId;
        // 加载配置
        SeacraftSouthSeaConfigMgr.reloadConfig(activityId);
        // 加载数据库数据
        loadData();
        initActivityInfo();
    }

    public SeacraftSouthSeaActivity(int activityId, int groupId) {
        this.activityId = activityId;
        this.groupId = groupId;
    }

    public void initActivityInfo(Map<String, SeacraftSouthSeaUnionInfo> unionInfoTempMap, Map<Long, SeacraftSouthSeaCrossUserInfo> userInfoTempMap) {
        for (SeacraftSouthSeaUnionInfo unionInfo : unionInfoTempMap.values()) {
            String unionId = unionInfo.getUnionData().getUnionId();
            int dbGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, unionId);
            if (dbGroupId == groupId) {
                unionInfoMap.put(unionId, unionInfo);
            }
        }

        for (SeacraftSouthSeaCrossUserInfo crossUserInfo : userInfoTempMap.values()) {
            long userId = crossUserInfo.getBaseData().getUserId();
            int dbGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);
            if (dbGroupId == groupId) {
                userInfoMap.put(userId, crossUserInfo);
            }
        }
        initActivityInfo();
    }

    private void initActivityInfo() {
        // 晋级联盟
        unionInfoMap.values().forEach(e -> {
            if (e.getUnionData().getRound() > 0) {
                for (int i = 1; i <= e.getUnionData().getRound(); i++) {
                    List<String> list = promotionMap.get(i);
                    if (list == null) {
                        list = new ArrayList<>();
                        promotionMap.put(i, list);
                    }
                    list.add(e.getUnionData().getUnionId());
                }
                rankList.add(e);
            }
        });
        refreshUnionRank();
        // 竞猜数据
        userInfoMap.values().forEach(e -> {
            for (Map.Entry<Integer, SeacraftSouthSeaGuessInfo> entry : e.getBaseData().getGuessMap().entrySet()) {
                int round = entry.getKey();
                List<String> unionList = entry.getValue().getUnionList();
                Map<String, Integer> map = guessMap.get(round);
                if (map == null) {
                    map = new ConcurrentHashMap<>();
                    guessMap.put(round, map);
                }
                for (String unionId : unionList) {
                    int num = map.getOrDefault(unionId, 0);
                    map.put(unionId, num + 1);
                }
            }
        });
        for (Map.Entry<Integer, List<String>> entry : promotionMap.entrySet()) {
            if (entry.getKey() <= 1) {
                continue;
            }
            // 南海丝路 的轮次
            int round = entry.getKey() - 1;
            // 上一轮参赛的联盟
            List<String> promotionUnionList = promotionMap.get(round);
            // 前n名联盟集合
            List<String> unionTopNList = new ArrayList<>();
            SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
            // 竞猜的联盟数量
            int guessNum = activityConfig.getGuessUnionNumMap().getOrDefault(round, 0);
            for (String unionId : promotionUnionList) {
                SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
                SeacraftSouthSeaResultInfo resultInfo = unionInfo.getUnionData().getResultMap().get(round + 1);
                if (resultInfo != null && resultInfo.getRank() <= guessNum) {
                    unionTopNList.add(unionId);
                }
            }
            guessSuccess(round, unionTopNList, false);
        }

        refreshCurJoinUnionShip();
    }

    @Deprecated
    private void loadData() {
        Map<String, SeacraftSouthSeaCrossUnionData> unionDataMap = SeacraftSouthSeaBusiness.getSeacraftSouthSeaCrossUnionDataMap(activityId);
        unionDataMap.values().forEach(e -> {
            int dbGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, e.getUnionId());
            if (dbGroupId == groupId) {
                unionInfoMap.put(e.getUnionId(), new SeacraftSouthSeaUnionInfo(e));
            }
        });
        Map<String, SeacraftSouthSeaCrossUnionShipData> shipDataMap = SeacraftSouthSeaBusiness.getSeacraftSouthSeaCrossUnionShipDataMap(activityId);
        shipDataMap.values().forEach(e -> {
            int dbGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, e.getUnionId());
            if (dbGroupId == groupId) {
                SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(e.getUnionId());
                if (unionInfo == null) {
                    logger.error("海上争霸 南海丝路 有SeacraftSouthSeaCrossUnionShipData数据 却没有 联盟数据 activityId:{},unionId:{}", e.getActivityId(), e.getUnionId());
                } else {
                    unionInfo.setShipData(e);
                }
            }
        });

        Map<Long, SeacraftSouthSeaCrossUserData> userDataMap = SeacraftSouthSeaBusiness.getSeacraftSouthSeaCrossUserDataMap(activityId);
        userDataMap.values().forEach(e -> {
            int dbGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, e.getUserId());
            if (dbGroupId == groupId) {
                SeacraftSouthSeaCrossUserInfo userInfo = new SeacraftSouthSeaCrossUserInfo(e);
                userInfoMap.put(e.getUserId(), userInfo);
                if (!StringUtils.isNullOrEmpty(e.getUnionId())) {
                    SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(e.getUnionId());
                    if (unionInfo == null) {
                        logger.info("海上争霸 南海丝路 有SeacraftSouthSeaCrossUserData数据 却没有 联盟数据 activityId:{},unionId:{},userId:{}", e.getActivityId(), e.getUnionId(), e.getUserId());
                    } else {
                        unionInfo.getMemberMap().put(e.getUserId(), userInfo);
                    }
                }
            }
        });
        Map<Long, SeacraftSouthSeaCrossChallengeData> challengeMap = SeacraftSouthSeaBusiness.getSeacraftSouthSeaCrossChallengeDataMap(activityId);
        challengeMap.values().forEach(e -> {
            int dbGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, e.getUserId());
            if (dbGroupId == groupId) {
                SeacraftSouthSeaCrossUserInfo userInfo = userInfoMap.get(e.getUserId());
                if (userInfo == null) {
                    logger.error("海上争霸 南海丝路 有SeacraftSouthSeaCrossChallengeData数据 却没有 玩家数据 activityId:{},userId:{}", e.getActivityId(), e.getUserId());
                } else {
                    userInfo.setChallengeData(e);
                }
            }
        });
        int curRound = getCurRound();
        long time = 0;
        if (curRound > 0) {
            time = SeacraftSouthSeaMgr.getRoundStartTime(activityId, curRound);
        }
        List<SeacraftSouthSeaBattleDetailData> battleDetailList = SeacraftSouthSeaBusiness.getSeacraftSouthSeaBattleDetailDataList(activityId, time);
        battleDetailList.forEach(e -> {
            int dbGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, e.getUnionId());
            if (dbGroupId == groupId) {
                SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(e.getUnionId());
                if (unionInfo == null) {
                    logger.error("海上争霸 南海丝路 有SeacraftSouthSeaBattleDetailData数据 却没有 联盟数据 activityId:{},unionId:{}", e.getActivityId(), e.getUnionId());
                } else {
                    if (e.getMasterType() == 0) {
                        unionInfo.getAttackBattleMap().put(e.getTargetUnionId(), e);
                    } else if (e.getMasterType() == 1) {
                        unionInfo.getDefendBattleMap().put(e.getTargetUnionId(), e);
                    }
                }
            }
        });
        List<SeacraftSouthSeaCrossRecordData> list = SeacraftSouthSeaBusiness.getSeacraftSouthSeaCrossRecordDataList(activityId, time);
        list.forEach(e -> {
            int dbGroupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, e.getUnionId());
            if (dbGroupId == groupId) {
                SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(e.getUnionId());
                if (unionInfo == null) {
                    logger.error("海上争霸 南海丝路 有SeacraftSouthSeaCrossRecordData数据 却没有 联盟数据 activityId:{},unionId:{}", e.getActivityId(), e.getUnionId());
                } else {
                    unionInfo.addRecord(e);
                }
            }
        });
    }

    public void save() {
        for (SeacraftSouthSeaUnionInfo item : unionInfoMap.values()) {
            // union
            if (item.getUnionData().isUpdateOption()) {
                SeacraftSouthSeaBusiness.updateSeacraftSouthSeaCrossUnionData(item.getUnionData());
            } else if (item.getUnionData().isInsertOption()) {
                SeacraftSouthSeaBusiness.addSeacraftSouthSeaCrossUnionData(item.getUnionData());
            }
            // ship
            if (item.getShipData() != null) {
                if (item.getShipData().isUpdateOption()) {
                    SeacraftSouthSeaBusiness.updateSeacraftSouthSeaCrossUnionShipData(item.getShipData());
                } else if (item.getShipData().isInsertOption()) {
                    SeacraftSouthSeaBusiness.addSeacraftSouthSeaCrossUnionShipData(item.getShipData());
                }
            }
            for (SeacraftSouthSeaBattleDetailData battleDetailData : item.getAttackBattleMap().values()) {
                if (battleDetailData.isUpdateOption()) {
                    SeacraftSouthSeaBusiness.updateSeacraftSouthSeaBattleDetailData(battleDetailData);
                } else if (battleDetailData.isInsertOption()) {
                    SeacraftSouthSeaBusiness.addSeacraftSouthSeaBattleDetailData(battleDetailData);
                }
            }

            for (SeacraftSouthSeaBattleDetailData battleDetailData : item.getDefendBattleMap().values()) {
                if (battleDetailData.isUpdateOption()) {
                    SeacraftSouthSeaBusiness.updateSeacraftSouthSeaBattleDetailData(battleDetailData);
                } else if (battleDetailData.isInsertOption()) {
                    SeacraftSouthSeaBusiness.addSeacraftSouthSeaBattleDetailData(battleDetailData);
                }
            }

            // 攻击
            for (SeacraftSouthSeaCrossRecordData recordData : item.getAttackRecordList()) {
                if (recordData.isUpdateOption()) {
                    SeacraftSouthSeaBusiness.updateSeacraftSouthSeaCrossRecordData(recordData);
                } else if (recordData.isInsertOption()) {
                    SeacraftSouthSeaBusiness.addSeacraftSouthSeaCrossRecordData(recordData);
                }
            }
            // 防守
            for (SeacraftSouthSeaCrossRecordData recordData : item.getDefendRecordList()) {
                if (recordData.isUpdateOption()) {
                    SeacraftSouthSeaBusiness.updateSeacraftSouthSeaCrossRecordData(recordData);
                } else if (recordData.isInsertOption()) {
                    SeacraftSouthSeaBusiness.addSeacraftSouthSeaCrossRecordData(recordData);
                }
            }
        }
        for (SeacraftSouthSeaCrossUserInfo item : userInfoMap.values()) {
            if (item.getBaseData().isUpdateOption()) {
                SeacraftSouthSeaBusiness.updateSeacraftSouthSeaCrossUserData(item.getBaseData());
            } else if (item.getBaseData().isInsertOption()) {
                SeacraftSouthSeaBusiness.addSeacraftSouthSeaCrossUserData(item.getBaseData());
            }
            // 挑战数据
            if (item.getChallengeData() != null) {
                if (item.getChallengeData().isUpdateOption()) {
                    SeacraftSouthSeaBusiness.updateSeacraftSouthSeaCrossChallengeData(item.getChallengeData());
                } else if (item.getChallengeData().isInsertOption()) {
                    SeacraftSouthSeaBusiness.addSeacraftSouthSeaCrossChallengeData(item.getChallengeData());
                }
            }
        }
    }

    /**
     * 刷新联盟排行榜
     */
    public void refreshUnionRank() {
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            return;
        }
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId, true);
        if (crossActivityDetail.getParam1() <= 0) {
            return;
        }
        refreshCurJoinUnionShip();
        long now = DateHelper.getCurrentTime();
        for (SeacraftSouthSeaUnionInfo item : rankList) {
            item.distance = item.getDistance(this, (int) crossActivityDetail.getParam1(), now);
        }
        rankList.sort((t1, t2) -> {
            if (t1.getUnionData().getRound() != t2.getUnionData().getRound()) {
                // 晋级到的轮次不同
                return Integer.compare(t2.getUnionData().getRound(), t1.getUnionData().getRound());
            } else {
                if (t1.getUnionData().getRound() == crossActivityDetail.getParam1()) {
                    if (t1.distance != t2.distance) {
                        // 行驶的距离不同
                        return Long.compare(t2.distance, t1.distance);
                    } else {
                        if (t1.distance == getRoundDistance() && t1.getShipData().getEndTime() != t2.getShipData().getEndTime()) {
                            // 到达了终点 到达时间不同
                            return Long.compare(t1.getShipData().getEndTime(), t2.getShipData().getEndTime());
                        }
                    }
                }
                return Integer.compare(t1.getUnionData().getRank(), t2.getUnionData().getRank());
            }
        });
    }

    /**
     * 不在比赛阶段的排序
     */
//    public void shipSort() {
//        curJoiningList.sort((t1, t2) -> {
//            if (t1.getShipData().getEndTime() != 0 && t2.getShipData().getEndTime() != 0) {
//                // 二者都到达情况
//                if(t1.getShipData().getEndTime() != t2.getShipData().getEndTime()){
//                    return Long.compare(t1.getShipData().getEndTime(), t2.getShipData().getEndTime());
//                }else {
//                    // 到达时间相同比较 上一轮排名
//                    return Long.compare(t1.getUnionData().getRank(), t2.getUnionData().getRank());
//                }
//            }
//            if (t1.getShipData().getEndTime() != 0 && t2.getShipData().getEndTime() == 0) {
//                return -1;
//            }
//            if (t1.getShipData().getEndTime() == 0 && t2.getShipData().getEndTime() != 0) {
//                return 1;
//            }
//            // 二者未到达情况
//            if(t1.getShipData().getDistance() != t2.getShipData().getDistance()){
//                return Long.compare(t2.getShipData().getDistance(), t1.getShipData().getDistance());
//            }
//            return Long.compare(t1.getUnionData().getRank(), t2.getUnionData().getRank());
//        });
//    }

    /**
     * 锁定晋级南海丝路 的名额
     *
     * @param activityId
     * @param unionList
     */
    public synchronized void lockPromotionUnion(int activityId, List<String> unionList, int round) {
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        if (crossActivityDetail.getParam1() >= round) {
            logger.info("锁定 海上争霸 南海丝路 的联盟名额。不需要重复锁定晋级名额 param1: {},round:{},activityId:{} ,unionList:{}", crossActivityDetail.getParam1(), round, activityId, StringUtils.listToString(unionList, ","));
            return;
        }
        if (unionList == null || unionList.size() == 0) {
            logger.info("锁定 海上争霸 南海丝路 的联盟名额。收到的联盟晋级数量为0 。 param1: {},round:{},activityId:{} ,unionList:{}", crossActivityDetail.getParam1(), round, activityId, StringUtils.listToString(unionList, ","));
            return;
        }
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        // 找到对应 的晋级名单
        int promotionNum = SeacraftSouthSeaCommonMgr.thisRoundPromotionNum(round, activityConfig);
        long now = DateHelper.getCurrentTime();
        // 晋级的联盟
        List<String> promotionUnionList = new ArrayList<>();

        // 竞猜的玩家数量
        int num = activityConfig.getGuessUnionNumMap().getOrDefault(round - 1, 0);
        // 前n名联盟集合
        List<String> unionTopNList = new ArrayList<>();

        for (int i = 0; i < unionList.size(); i++) {
            // 晋级数量
            int rank = i + 1;
            SeacraftSouthSeaUnionInfo unionInfo = null;
            if (round == 1 && promotionUnionList.size() <= promotionNum) {
                unionInfo = getUnionInfo(unionList.get(i), true);
            } else {
                unionInfo = getUnionInfo(unionList.get(i), false);
            }
            if (unionInfo != null) {
                unionInfo.getUnionData().setRank(rank);
                if (round > 1) {
                    long distance = 0;
                    long arriveTime = 0;
                    long totalDurable = 0;
                    if (unionInfo.getShipData() != null) {
                        // 到达时间
                        arriveTime = unionInfo.getShipData().getEndTime();
                        distance = unionInfo.getShipData().getDistance();
                        totalDurable = unionInfo.getShipData().getTotalDurable();
                    }
                    unionInfo.getUnionData().getResultMap().put(round, new SeacraftSouthSeaResultInfo(arriveTime, distance, rank));
                    unionInfo.getUnionData().setUpdateOption();
                    // 加日志
                    int lv = SeacraftSouthSeaMgr.getShipConfig(unionInfo).getLevel();
//                    SeacraftSouthSeaLogMgr.addLogSeacraftSouthSeaRoundShip(new LogSeacraftSouthSeaRoundShip(activityId, unionInfo.getUnionData().getUnionId(), round, lv, distance, totalDurable, arriveTime, now));
                    CrossAutoLogMgr.add(new LogSeacraftSouthSeaRoundShip(activityId, unionInfo.getUnionData().getUnionId(), round, lv, distance, totalDurable, arriveTime, now));
                } else {
                    // 海盗之乱晋级信息
                    unionInfo.getUnionData().getResultMap().put(round, new SeacraftSouthSeaResultInfo(now, 0, rank));
                    unionInfo.getUnionData().setUpdateOption();
                    rankList.add(unionInfo);
                }
                if (promotionUnionList.size() < promotionNum) {
                    promotionUnionList.add(unionInfo.getUnionData().getUnionId());
                    unionInfo.getUnionData().setRound(round);
                }

                if (unionTopNList.size() < num) {
                    unionTopNList.add(unionInfo.getUnionData().getUnionId());
                }
            }
        }
        if (promotionUnionList.size() > 0) {
            promotionMap.put(round, promotionUnionList);
        }
        if (unionTopNList.size() > 0 && round > 1) {
            guessSuccess(round - 1, unionTopNList, true);
        }
        crossActivityDetail.setParam1(round);
    }

    /**
     * 同步锁定联盟的联盟成员给跨服
     *
     * @param unionList
     */
    public void synPromotionUnion(List<SeacraftSouthSeaProto.SeacraftSouthSeaUnionInfo> unionList) {
        for (SeacraftSouthSeaProto.SeacraftSouthSeaUnionInfo item : unionList) {
            logger.info("海上争霸 收到来着区服的联盟数据 activityId:{},unionId:{},memberNum:{}", activityId, item.getUnionId(), item.getMemberInfoListList().size());
            SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(item.getUnionId(), true);
            unionInfo.getUnionData().setUnionBaseInfo(UnionBasePb.parseUnionBaseInfo(item.getUnionBaseInfo()));
            item.getMemberInfoListList().forEach(e -> {
                // 锁定小队
                getUserInfo(e.getUserId(), item.getUnionId(), e.getServerId());
                // 做个保护防止 联盟成员时变更没有同步
                joinUnion(e.getUserId(), item.getUnionId());
            });

            // 热更代码 start
            // 校验商会成员数据
            try{
                StringBuilder sb = new StringBuilder();
                for (SeacraftSouthSeaProto.SeacraftSouthSeaUnionMemberInfo memberInfo : item.getMemberInfoListList()){
                    sb.append(memberInfo.getUserId()).append(",");
                }
                logger.info("海上争霸 收到来着区服的联盟数据 activityId:{},unionId:{},memberNum:{},memberList:{}", activityId, item.getUnionId(), item.getMemberInfoListList().size(), sb.toString());
                long now = System.currentTimeMillis();
                if(item.getMemberInfoListList().size() <= 0){
                    return;
                }
                Iterator<Long> memberIterator = unionInfo.getMemberMap().keySet().iterator();
                while (memberIterator.hasNext()){
                    long userId = memberIterator.next();

                    boolean flag = false;
                    for (SeacraftSouthSeaProto.SeacraftSouthSeaUnionMemberInfo memberInfo : item.getMemberInfoListList()){
                        if(memberInfo.getUserId() == userId){
                            flag = true;
                            break;
                        }
                    }
                    if(!flag){
                        // 移除联盟成员
                        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
                        if(userInfo != null) {
                            // 扣除 已经捐献数据
                            for (Map.Entry<Integer, Long> entry : userInfo.getBaseData().getDonationShipMap().entrySet()) {
                                unionInfo.addDonationShip(entry.getKey(), -entry.getValue(), now);
                            }
                            unionInfo.getUnionData().setUpdateOption();
                            userInfo.getBaseData().setUnionId("");
                            memberIterator.remove();
                        }
                        logger.error("同步锁定联盟的联盟成员给跨服 时，校验数据，移除不在联盟的玩家数据， 玩家:{}",userId);
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            // 热更代码 end
        }
    }


    /**
     * @param userTeamInfoList
     */
    public void synUserTeamInfo(List<SeacraftSouthSeaProto.SeacraftSouthSeaLockUserInfo> userTeamInfoList) {
        long now = DateHelper.getCurrentTime();
        for (SeacraftSouthSeaProto.SeacraftSouthSeaLockUserInfo lockUserInfo : userTeamInfoList) {
            SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(lockUserInfo.getUserId());
            if (userInfo != null) {
                if (lockUserInfo.hasPlayerInfo()) {
                    CrossUserMgr.updateUserBaseInfo(lockUserInfo.getUserId(), PlayerBasePb.parseToUserBaseInfo(lockUserInfo.getPlayerInfo()));
                }
                for (SeacraftSouthSeaProto.SeacraftSouthSeaLockTeamInfo item : lockUserInfo.getTeamInfoList()) {
                    SeacraftSouthSeaTeamInfo teamInfo = new SeacraftSouthSeaTeamInfo();
                    for (SeacraftSouthSeaProto.SeacraftSouthSeaPatronsEntity patronsEntity : item.getPatronsList()) {
                        teamInfo.getTeamList().add(parseSouthSeaPatronsInfo(patronsEntity));
                    }
                    userInfo.getBaseData().getShipMemberMap().put(item.getType(), teamInfo);
                    userInfo.getBaseData().setUpdateOption();
                    // 船员小队组队日志
                    addLogSeacraftSouthSeaTeam(userInfo, teamInfo, item.getType(), now);
                }
            }
        }
    }

    /**
     * 区服索要 联盟数据 和联盟成员的门客数据
     */
    public synchronized void synUnionInfo() {
        int round = getCurRound();
        if (round <= 0) {
            return;
        }
        // 返回需要同步的联盟数据
        List<String> returnUnionInfoList = new ArrayList<>();
        // 返回需要同步的玩家门客队伍数据
        Set<Long> returnUserTeamList = new HashSet<>();
        // 需要从海盗之乱晋级上来所有联盟的数据
        List<String> promotionList = promotionMap.get(1);
        if (promotionList != null) {
            for (String unionId : promotionList) {
                SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
                if (unionInfo != null) {
                    if (!unionInfo.isSynUnionInfo()) {
                        // 判断是否需要同步联盟数据
                        returnUnionInfoList.add(unionId);
                    }
                    for (SeacraftSouthSeaCrossUserInfo userInfo : unionInfo.getMemberMap().values()) {
                        if (userInfo.getBaseData().getShipMemberMap().size() == 0) {
                            returnUserTeamList.add(userInfo.getBaseData().getUserId());
                        }
                    }
                }
            }
            if (returnUnionInfoList.size() > 0) {
                isSyn.set(false);
            } else {
                if (promotionList.size() > 0) {
                    isSyn.compareAndSet(false, true);
                }
            }
        }
        if (returnUnionInfoList.size() > 0 || returnUserTeamList.size() > 0) {
            // 去各个区服锁定 联盟成员
            ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
            if (activityInfo != null) {
                SeacraftSouthSeaProto.SeacraftSouthSeaSynPromotionUnionCrossToGameMsg.Builder builder = getPromotionUnion();
                builder.addAllReturnUnionInfoList(returnUnionInfoList);
                builder.addAllReturnUserTeamList(returnUserTeamList);
                for (Long serverId : activityInfo.getServerIdList()) {
                    MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(GameProtocol.S_SEACRAFT_SOUTH_SEA_LOCK_JOIN_UNION_FROM_CROSS, builder));
                }
            }
        }
    }


    /**
     * 进入南海丝路
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaEnterRespMsg.Builder southSeaEnter(long userId, long refreshTime, String unionId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaEnterRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaEnterRespMsg.newBuilder();
        refreshCurJoinUnionShip();
        int promotionNum = thisRoundPromotionNum();
        long now = DateHelper.getCurrentTime();
        for (int i = 0; i < promotionNum; i++) {
            if (rankList.size() <= i) {
                break;
            }
            SeacraftSouthSeaUnionInfo item = rankList.get(i);
            if(item != null && item.getShipData() != null){
                if (item.getShipData().getRefreshTime() > refreshTime) {
                    item.refreshFixShip(now);
                    builder.addShipInfoList(item.builderSeacraftSouthSeaShipInfo());
                }
            }
        }
        inActivitySet.add(userId);
        builder.setRank(getUserRank(userId));
        if (refreshTime == 0 && lastMarqueeInfo != null) {
            builder.setMarqueeInfo(lastMarqueeInfo);
        }
        builder.setRefreshTime(DateHelper.getCurrentTime());
        SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (unionInfo != null && unionInfo.getUnionData().getRound() == crossActivityDetail.getParam1() && activityConfig != null) {
            // 我方商会进攻目标
            List<SeacraftSouthSeaBattleDetailData> list = new ArrayList<>(unionInfo.getAttackBattleMap().values());
            for (SeacraftSouthSeaBattleDetailData item : list) {
                calTotalDamage(item);
            }
            list.sort((t1, t2) -> {
                if (t1.getTotalDamage() != t2.getTotalDamage()) {
                    return Long.compare(t2.getTotalDamage(), t1.getTotalDamage());
                } else {
                    return Long.compare(t1.getTime(), t2.getTime());
                }
            });
            int num = Math.min(list.size(), activityConfig.getAttackRankList().get(0));
            for (int i = 0; i < num; i++) {
                builder.addAttackUnionList(list.get(i).getTargetUnionId());
            }
            // 进攻我方的敌方商会
            list = new ArrayList<>(unionInfo.getDefendBattleMap().values());
            for (SeacraftSouthSeaBattleDetailData item : list) {
                calTotalDamage(item);
            }
            list.sort((t1, t2) -> {
                if (t1.getTotalDamage() != t2.getTotalDamage()) {
                    return Long.compare(t2.getTotalDamage(), t1.getTotalDamage());
                } else {
                    return Long.compare(t1.getTime(), t2.getTime());
                }
            });
            num = Math.min(list.size(), activityConfig.getAttackRankList().get(1));
            for (int i = 0; i < num; i++) {
                builder.addUnderAttackUnionList(list.get(i).getTargetUnionId());
            }
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 竞猜成功
     *
     * @param round     竞猜轮   南海丝路的轮次 从1开始
     * @param unionList 前n名联盟信息
     */
    public void guessSuccess(int round, List<String> unionList, boolean isBroadcast) {
        userInfoMap.values().forEach(e -> {
            // 猜中的数量
            SeacraftSouthSeaGuessInfo southSeaGuessInfo = e.getBaseData().getGuessMap().get(round);
            if (southSeaGuessInfo != null) {
                int num = 0;
                for (String unionId : southSeaGuessInfo.getUnionList()) {
                    if (unionList.contains(unionId)) {
                        num++;
                    }
                }
                Map<Integer, List<Long>> map = guessTimesMap.get(round);
                if (map == null) {
                    map = new ConcurrentHashMap<>();
                    guessTimesMap.put(round, map);
                }
                List<Long> list = map.get(num);
                if (list == null) {
                    list = new ArrayList<>();
                    map.put(num, list);
                }
                list.add(e.getBaseData().getUserId());

                if (isBroadcast) {
                    SeacraftSouthSeaProto.BroadcastSeacraftSouthSeaRespMsg.Builder broadcast = SeacraftSouthSeaProto.BroadcastSeacraftSouthSeaRespMsg.newBuilder();
                    broadcast.setType(3);
                    broadcast.setGuessInfo(SeacraftSouthSeaProto.SeacraftSouthSeaGuessInfo.newBuilder().setRound(round).addAllUnionList(southSeaGuessInfo.getUnionList()).setIsReceive(southSeaGuessInfo.isReceive()).setNum(num));
                    MessageHelper.sendPacket(e.getBaseData().getServerId(), e.getBaseData().getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_SEACRAFT_SOUTH_SEA_BROADCAST, broadcast));
                }
            }
        });
    }

    /**
     * 船只到达刷新任务
     */
    public void arrivalTask() {
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            return;
        }
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        if (crossActivityDetail.getParam1() < 1 || crossActivityDetail.getParam1() > activityConfig.roundTimeList.size()) {
            return;
        }
        int round = (int) crossActivityDetail.getParam1();
        long now = DateHelper.getCurrentTime();

        if (!SeacraftSouthSeaMgr.inRoundTime(activityId, round, now)) {
            return;
        }
        refreshUnionRank();
        for (SeacraftSouthSeaUnionInfo item : rankList) {
            if (item.getUnionData().getRound() == crossActivityDetail.getParam1() && item.getShipData() != null) {
                // 如果到达了 未广播则广播
                if (item.getShipData().getEndTime() > 0 && !item.getUnionData().getResultMap().containsKey(round + 1)) {
                    item.arrivalBroadcast(this);
                }
//              logger.info("当前船只unionId:{},名称：{}，未抵达，上一轮rank :{},已行驶距离：{}", item.getUnionData().getUnionId(), item.getUnionData().getUnionBaseInfo().getUnionName(), item.getUnionData().getRank(), item.getDistance((int) (crossActivityDetail.getParam1()), now));
            }
        }
    }

    public SeacraftSouthSeaUnionInfo getUnionInfo(String unionId, boolean newIfNull) {
        SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
        if (unionInfo == null && newIfNull) {
            if (!StringUtils.isNullOrEmpty(unionId)) {
                synchronized (unionInfoMap) {
                    unionInfo = unionInfoMap.get(unionId);
                    if (unionInfo == null) {
                        SeacraftSouthSeaCrossUnionData unionData = new SeacraftSouthSeaCrossUnionData();
                        unionData.setActivityId(activityId);
                        unionData.setUnionId(unionId);
                        unionData.setInsertOption();

                        unionInfo = new SeacraftSouthSeaUnionInfo(unionData);
                        unionInfoMap.put(unionId, unionInfo);
                    }
                }
            }
        }
        return unionInfo;
    }

    //获取榜首N名商会的UId
    public List<String> getRankTop(int lowestRank) {
        List<String> topList = new ArrayList<>();
        Map<Integer, String> topInfo = new ConcurrentHashMap<>();
        for (Map.Entry<String, SeacraftSouthSeaUnionInfo> infoEntry : unionInfoMap.entrySet()) {
            int tmpRank = infoEntry.getValue().getUnionData().getRank();
            if (tmpRank > 0 && tmpRank <= lowestRank) {
                topInfo.put(tmpRank, infoEntry.getValue().getUnionData().getUnionId());
            }
        }
        if (topInfo.size() > lowestRank) {
            logger.info("海上争霸活动 activityId = {},前{}名内有{}个玩家,存在数据异常", activityId, lowestRank, topInfo.size());
            return null;
        }
        int rankNum = lowestRank <= topInfo.size() ? lowestRank : topInfo.size();
        for (int i = 1; i <= rankNum; i++) {
            if (StringUtils.isNullOrEmpty(topInfo.get(i))) {
                logger.info("海上争霸活动 activityId = {},第{}名没有玩家,存在数据异常", activityId, i);
                return null;
            } else {
                topList.add(topInfo.get(i));
            }
        }

        return topList;
    }

    /**
     * 组装玩家数据
     *
     * @param userId
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaUserInfo.Builder getSeacraftSouthSeaUserInfo(long userId, String unionId, long serverId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaUserInfo.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaUserInfo.newBuilder();
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId, unionId, serverId);
        if (userInfo != null) {
            refreshUser(userInfo);
            for (Map.Entry<Integer, SeacraftSouthSeaTeamInfo> entry : userInfo.getBaseData().getShipMemberMap().entrySet()) {
                SeacraftSouthSeaProto.SeacraftSouthSeaShipTeamInfo.Builder teamInfo = SeacraftSouthSeaProto.SeacraftSouthSeaShipTeamInfo.newBuilder();
                teamInfo.setType(entry.getKey());
                teamInfo.setAttackTimes(entry.getValue().getTimes());
                teamInfo.setRaidAttackTimes(entry.getValue().getRaidTimes());
                for (SeacraftSouthSeaPatronsInfo item : entry.getValue().getTeamList()) {
                    teamInfo.addPatronsId(item.getId());
                }
                builder.addShipTeamList(teamInfo);
            }
            builder.setRaidAttackTimes(userInfo.getBaseData().getRaidAttackTimes());
            builder.setRound(userInfo.getBaseData().getRound());
            if (userInfo.getChallengeData() != null) {
                builder.setUnionId(userInfo.getChallengeData().getTargetId());
            }

            for (Map.Entry<Integer, SeacraftSouthSeaGuessInfo> entry : userInfo.getBaseData().getGuessMap().entrySet()) {
                int num = getGuessNum(userInfo, entry.getKey());
                builder.addGuessList(SeacraftSouthSeaProto.SeacraftSouthSeaGuessInfo.newBuilder().setRound(entry.getKey()).addAllUnionList(entry.getValue().getUnionList()).setIsReceive(entry.getValue().isReceive()).setNum(num));
            }
            builder.setRank(getUserRank(userId));
            builder.setAllScore(getUserScore(userId));
            builder.setFloor(userInfo.getBaseData().getFloor());

        }
        return builder;
    }

    /**
     * 获取自己联盟的船只信息
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaShipInfo.Builder getUnionShip(long userId) {
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo == null) {
            return null;
        }
        if (StringUtils.isNullOrEmpty(userInfo.getBaseData().getUnionId())) {
            return null;
        }
        SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(userInfo.getBaseData().getUnionId());
        if (unionInfo == null) {
            return null;
        }
        if (unionInfo.getShipData() == null) {
            return null;
        }
        return unionInfo.builderSeacraftSouthSeaShipInfo();
    }

    /**
     * 捐献
     *
     * @param userId
     * @param serverId
     * @param unionId
     * @param propId
     * @param num
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaDonationShipRespMsg.Builder donationShip(long userId, long serverId, String unionId, int propId, int num) {
        SeacraftSouthSeaProto.SeacraftSouthSeaDonationShipRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaDonationShipRespMsg.newBuilder();
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_CONFIG);
            return builder;
        }
        ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
        if (!SeacraftSouthSeaCommonMgr.isPrepareTime(activityInfo, activityConfig)) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_IN_PRETIME);
            return builder;
        }
        int index = activityConfig.donateList.indexOf(propId);
        if (index < 0) {
            // 道具id 错误
            builder.setRet(GameErrorCode.E_BAG_ITEM_CAN_NO_USE);
            return builder;
        }
        Property reward = addDonationShip(userId, unionId, serverId, propId, num, index);
        builder.setReward(PropertyHelper.parsePropertyToString(reward));
        builder.setRet(0);
        return builder;
    }

    /**
     * 加贡献
     *
     * @param userId
     * @param unionId
     * @param propId
     * @param num
     */
    public Property addDonationShip(long userId, String unionId, long serverId, int propId, int num, int index) {
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId, unionId, serverId);
        Property reward = new Property();
        GoodsInfo goodsInfo = GoodsMgr.getGoodsInfo(propId);
        int singleValue = goodsInfo.getParamList().get(0).intValue();
        int addValue = singleValue * num;
        for (int i = 0; i < num; i++) {
            String extendParam = goodsInfo.getExtendParam();
            Property property = RandomWeightConfigHelper.getRandomProperty(extendParam);
            reward.addProperty(property);
        }
        long oldValue = userInfo.getBaseData().getDonationShipMap().getOrDefault(index, 0L);
        long newValue = oldValue + addValue;
        userInfo.getBaseData().getDonationShipMap().put(index, newValue);
        userInfo.getBaseData().setUpdateOption();
        long unionOldValue = 0;
        long unionNewValue = 0;
        long now = DateHelper.getCurrentTime();
        if (!StringUtils.isNullOrEmpty(unionId)) {
            SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, true);
            unionOldValue = unionInfo.getUnionData().getDonationShipMap().getOrDefault(index, 0L);
            unionInfo.addDonationShip(index, addValue, now);
            unionNewValue = unionInfo.getUnionData().getDonationShipMap().getOrDefault(index, 0L);
        }
        // 加日志
//        SeacraftSouthSeaLogMgr.addLogSeacraftSouthSeaDonation(new LogSeacraftSouthSeaDonation(activityId, userId, userInfo.getBaseData().getUnionId(), index, addValue, oldValue, newValue, unionOldValue, unionNewValue, 1, now));
        CrossAutoLogMgr.add(new LogSeacraftSouthSeaDonation(activityId, userId, userInfo.getBaseData().getUnionId(), index, addValue, oldValue, newValue, unionOldValue, unionNewValue, 1, now));

        return reward;
    }

    /**
     * 查看船只捐献详情
     *
     * @param userId
     * @param unionId
     * @param type
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetDonationShipDetailRespMsg.Builder getDonationShipDetail(long userId, String unionId, int type) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetDonationShipDetailRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetDonationShipDetailRespMsg.newBuilder();
        if (!StringUtils.isNullOrEmpty(unionId)) {
            SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
            if (unionInfo != null) {
                for (SeacraftSouthSeaCrossUserInfo item : unionInfo.getMemberMap().values()) {
                    Long num = item.getBaseData().getDonationShipMap().get(type);
                    if (num != null && num > 0) {
                        SeacraftSouthSeaProto.SeacraftSouthSeaDonationDetail.Builder detail = SeacraftSouthSeaProto.SeacraftSouthSeaDonationDetail.newBuilder();
                        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(item.getBaseData().getUserId());
                        if (userBaseInfo != null) {
                            detail.setMemberName(userBaseInfo.getNickName());
                        }
                        detail.setPartInfo(SeacraftSouthSeaProto.SeacraftSouthSeaShipPartInfo.newBuilder().setType(type).setValue(num));
                        builder.addDonationDetailList(detail);
                    }
                }
            }
        } else {
            SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
            if (userInfo != null) {
                Long num = userInfo.getBaseData().getDonationShipMap().get(type);
                if (num != null && num > 0) {
                    SeacraftSouthSeaProto.SeacraftSouthSeaDonationDetail.Builder detail = SeacraftSouthSeaProto.SeacraftSouthSeaDonationDetail.newBuilder();
                    UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
                    if (userBaseInfo != null) {
                        detail.setMemberName(userBaseInfo.getNickName());
                    }
                    detail.setPartInfo(SeacraftSouthSeaProto.SeacraftSouthSeaShipPartInfo.newBuilder().setType(type).setValue(num));
                    builder.addDonationDetailList(detail);
                }
            }
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 查看船只详情
     *
     * @param unionId
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetShipRecordRespMsg.Builder getShipRecord(String unionId, int type) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetShipRecordRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetShipRecordRespMsg.newBuilder();
        SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
        if (unionInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_SHIP_NOT_EXIST);
            return builder;
        }
        List<SeacraftSouthSeaCrossRecordData> recordList = new ArrayList<>();
        if (type == 0) {
            recordList = new ArrayList<>(unionInfo.getAttackRecordList());
        } else if (type == 1) {
            recordList = new ArrayList<>(unionInfo.getDefendRecordList());
        }
        for (SeacraftSouthSeaCrossRecordData item : recordList) {
            builder.addAttackRecordList(builderSeacraftSouthSeaShipRecordInfo(item));
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 南海丝路 进攻 / 突袭 / 使用道具进攻 / 修复
     *
     * @param type          0 进攻 1突袭 2使用道具进攻 3修复 5 使用船桨
     * @param userId        操作的玩家id
     * @param ownUnionId    执行者的联盟id
     * @param targetUnionId 目标联盟id
     * @param titleId       玩家等级
     * @param dispatchType  派遣小队类型
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaActionRespMsg.Builder action(int type, long userId, long serverId, String ownUnionId, String targetUnionId, int titleId, int dispatchType, int count, long preReduceCount, int propId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaActionRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaActionRespMsg.newBuilder();
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_CONFIG);
            return builder;
        }
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_PROMOTION);
            return builder;
        }
        int curRound = getCurRound();
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(userInfo.getBaseData().getUnionId(), false);
        // 自己的联盟没有晋级 不能执行
        if (unionInfo == null || unionInfo.getUnionData().getRound() != curRound) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_PROMOTION);
            return builder;
        }
        SeacraftSouthSeaUnionInfo targetUnion = null;
        if (type == 0 || type == 2) {
            targetUnion = getUnionInfo(targetUnionId, false);
            // 自己的联盟没有晋级 不能执行
            if (targetUnion == null || targetUnion.getUnionData().getRound() != curRound) {
                builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TARGET_NO_PROMOTION);
                return builder;
            }
        }
        refreshUser(userInfo);
        long now = DateHelper.getCurrentTime();
        refreshCurJoinUnionShip();
        switch (type) {
            case 0: {
                // 进攻
                if (targetUnionId.equals(ownUnionId)) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_CAN_ATTACK_UNION);
                    return builder;
                }
                SeacraftSouthSeaTeamInfo seaTeamInfo = userInfo.getBaseData().getShipMemberMap().get(dispatchType);
                if (seaTeamInfo == null) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TEAM_NO_EXIST);
                    return builder;
                }
                if (userInfo.getChallengeData() != null && !StringUtils.isNullOrEmpty(userInfo.getChallengeData().getTargetId())) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_HAS_CHALLENGE);
                    return builder;
                }
                // 计算需要的道具
                if (activityConfig.attackItemCostList.size() <= seaTeamInfo.getTimes()) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TEAM_ATTACK_TIMES_LIMIT);
                    return builder;
                }
                // 判断消耗数量
                Integer needNum = activityConfig.attackItemCostList.get(seaTeamInfo.getTimes());
                if (preReduceCount < needNum) {
                    builder.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
                    return builder;
                }
//                if (unionInfo.isDamage()) {
//                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_DURABLE_TOO_LOW);
//                    return builder;
//                }
                if (targetUnion.isDamage()) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TARGET_DURABLE_TOO_LOW);
                    return builder;
                }
                if (targetUnion.isEnd(this, true)) {
                    int rank = getUnionRank(targetUnion, true);
                    if (rank > SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId).getSEACRAFT_CRAFT_SHIP_DISPLAY_NUM()) {
                        builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_THE_SHIP_IS_HIDE);
                        return builder;
                    }
                }
                boolean challengeSuccess = targetUnion.attacked(this, unionInfo, userInfo, dispatchType, 1);
                if (!challengeSuccess) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TARGET_UNION_RANK_ERROR);
                    return builder;
                }
                builder.setRealConsumeNum(needNum);
                builder.setChallengeInfo(builderSeacraftSouthSeaChallengeInfo(userInfo));
                builder.setShipInfo(targetUnion.builderSeacraftSouthSeaShipInfo());
            }
            break;
            case 1: {
                // 突袭
                if (userInfo.getChallengeData() != null && !StringUtils.isNullOrEmpty(userInfo.getChallengeData().getTargetId())) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_HAS_CHALLENGE);
                    return builder;
                }
//                if (unionInfo.isDamage()) {
//                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_DURABLE_TOO_LOW);
//                    return builder;
//                }
                if (userInfo.getBaseData().getRaidAttackTimes() >= activityConfig.getSEACRAFT_CRAFT_CHARGE_SINGLE_TIME()) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_USER_RAID_TIMES_NO_ENOUGH);
                    return builder;
                }
                SeacraftSouthSeaTeamInfo seaTeamInfo = userInfo.getBaseData().getShipMemberMap().get(dispatchType);
                if (seaTeamInfo == null) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TEAM_NO_EXIST);
                    return builder;
                }
                if (seaTeamInfo.getRaidTimes() >= activityConfig.getSEACRAFT_CRAFT_CHARGE_TIME()) {
                    // 免费次数已经用完  判断道具
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TEAM_RAID_TIMES_NO_ENOUGH);
                    return builder;
                }
                // 随机联盟
                targetUnion = randomUnion(unionInfo);
                if (targetUnion == null) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_CAN_ATTACK_UNION);
                    return builder;
                }

                boolean challengeSuccess = targetUnion.attacked(this, unionInfo, userInfo, dispatchType, 0);
                if (!challengeSuccess) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TARGET_UNION_RANK_ERROR);
                    return builder;
                }
                builder.setChallengeInfo(builderSeacraftSouthSeaChallengeInfo(userInfo));
                builder.setShipInfo(targetUnion.builderSeacraftSouthSeaShipInfo());
            }
            break;
            case 2: {
                if (targetUnionId.equals(ownUnionId)) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_CAN_ATTACK_UNION);
                    return builder;
                }
                // 使用道具进攻
                targetUnion.refreshShip(this, now);
//                if (unionInfo.isDamage()) {
//                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_DURABLE_TOO_LOW);
//                    return builder;
//                }
                if (targetUnion.isDamage()) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_TARGET_DURABLE_TOO_LOW);
                    return builder;
                }
                long oldDurable = targetUnion.getShipData().getRemainDurable();
                int score = targetUnion.propAttacked(this, unionInfo, userInfo, count, titleId);
                userInfo.getBaseData().setScore(userInfo.getBaseData().getScore() + score);
                builder.setScore(score);
                builder.setShipInfo(targetUnion.builderSeacraftSouthSeaShipInfo());
                builder.setDurable(oldDurable - targetUnion.getShipData().getRemainDurable());
            }
            break;
//            case 3: {
//                // 修复
//                unionInfo.refreshShip(this, now);
//                long oldDurable = unionInfo.getShipData().getRemainDurable();
//                if (unionInfo.getShipData().getRemainDurable() >= unionInfo.getShipData().getTotalDurable()) {
//                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_DURABLE_FULL);
//                    return builder;
//                }
//                // 计算可用的数量
//                int maxNum = unionInfo.canUseFixGoodMaxNum(titleId);
//                if (maxNum <= 0) {
//                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_DURABLE_FULL);
//                    return builder;
//                }
//                int realNum = Math.min(count, maxNum);
//                int score = unionInfo.fix(this, userInfo, realNum, titleId);
//                userInfo.getBaseData().setScore(userInfo.getBaseData().getScore() + score);
//                builder.setScore(score);
//                builder.setShipInfo(unionInfo.builderSeacraftSouthSeaShipInfo());
//                builder.setDurable(unionInfo.getShipData().getRemainDurable() - oldDurable);
//                builder.setRealConsumeNum(realNum);
//            }
//            break;
            case 5: {
                // 使用加速道具
                unionInfo.refreshShip(this, now);
                if (unionInfo.isEnd(this, false)) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_SPEED);
                    return builder;
                }
                if (unionInfo.getSpeedRecordList().size() >= activityConfig.getSEACRAFT_CRAFT_SPEED_UP_LIMIT()) {
                    builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_SPEED_UP_LIMIT);
                    return builder;
                }
                unionInfo.useSpeedProp(this, userInfo, count, propId);
                builder.setShipInfo(unionInfo.builderSeacraftSouthSeaShipInfo());
                builder.setRealConsumeNum(count);
                break;
            }
            default:
                builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_ACTION_TYPE_NO_ERROR);
                return builder;
        }
        builder.setRank(getUserRank(userId));
        builder.setAllScore(getUserScore(userId));
        builder.setRet(0);
        return builder;
    }


    /**
     * 购买buff
     *
     * @param userId
     * @param buffId
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaBuyBuffRespMsg.Builder buyBuff(long userId, int buffId, int preReduceCount) {
        SeacraftSouthSeaProto.SeacraftSouthSeaBuyBuffRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaBuyBuffRespMsg.newBuilder();
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_CONFIG);
            return builder;
        }
        if (userInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        // 需要刷新玩家数据。 有可能进入下一轮 挑战还在
        refreshUser(userInfo);
        if (userInfo.getChallengeData() == null || StringUtils.isNullOrEmpty(userInfo.getChallengeData().getTargetId())) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        if (userInfo.getChallengeData().getBuyBuffId() > 0) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_BUY_BUFF);
            return builder;
        }
        int addValue = 0;
        // 判断是否 首次购买过
        boolean firstBuy = getBuyBuffValue(userInfo) <= 0 && userInfo.getChallengeData().getWinStreakNum() <= 0;
        int needNum = 0;
        if (firstBuy) {
            // 首次购买
            if (activityConfig.firstBuyCostList.size() < buffId) {
                builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_BUFF_NO_EXIST);
                return builder;
            }
            addValue = activityConfig.firstAddBuffList.get(buffId - 1);
            needNum = activityConfig.firstBuyCostList.get(buffId - 1);
        } else {
            if (activityConfig.buyCostList.size() < buffId) {
                builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_BUFF_NO_EXIST);
                return builder;
            }
            addValue = activityConfig.addBuffList.get(buffId - 1);
            needNum = activityConfig.buyCostList.get(buffId - 1);
        }
        if (needNum > preReduceCount) {
            builder.setRet(GameErrorCode.E_BAG_INGOTS_NO_ENOUGH);
            return builder;
        }
        addBuffToTeam(userInfo, buffId, addValue);

        builder.setChallengeInfo(builderSeacraftSouthSeaChallengeInfo(userInfo));
        builder.setCostNum(needNum);
        builder.setRet(0);
        return builder;
    }


    /**
     * 挑战
     *
     * @param userId
     * @param targetId
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaChallengeRespMsg.Builder challenge(long userId, long targetId, int type, int blood, int buffId, long goldNum) {
        SeacraftSouthSeaProto.SeacraftSouthSeaChallengeRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaChallengeRespMsg.newBuilder();
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_CONFIG);
            return builder;
        }
        SeacraftSouthSeaCrossUserInfo attacker = getUserInfo(userId);
        if (attacker == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        refreshUser(attacker);
        if (attacker.getChallengeData() == null || StringUtils.isNullOrEmpty(attacker.getChallengeData().getTargetId())) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        SeacraftSouthSeaUnionInfo targetUnion = unionInfoMap.get(attacker.getChallengeData().getTargetId());
        if (targetUnion == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        return targetUnion.challenged(this, attacker, targetId, type, blood, buffId, goldNum);
    }

    /**
     * 获取挑战信息
     *
     * @param userId
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetChallengeRespMsg.Builder getChallengeInfo(long userId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetChallengeRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetChallengeRespMsg.newBuilder();
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        refreshUser(userInfo);
        if (userInfo.getChallengeData() == null || StringUtils.isNullOrEmpty(userInfo.getChallengeData().getTargetId())) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        builder.setChallengeInfo(builderSeacraftSouthSeaChallengeInfo(userInfo));
        builder.setRet(0);
        return builder;
    }


    /**
     * 领取连胜奖励
     *
     * @param userId
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaReceiveWinStreakRewardRespMsg.Builder receiveWinStreakReward(long userId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaReceiveWinStreakRewardRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaReceiveWinStreakRewardRespMsg.newBuilder();
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        // 刷新
        refreshUser(userInfo);
        if (userInfo.getChallengeData() == null || StringUtils.isNullOrEmpty(userInfo.getChallengeData().getTargetId())) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NOT_HAS_CHALLENGE);
            return builder;
        }
        // 获取奖励
        if (!canRecWinStreakReward(userInfo)) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_REWARD);
            return builder;
        }
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        // 连胜奖励
        int type = userInfo.getChallengeData().getAttackType() == 0 ? 1 : 2;

        int round = getCurRound();
        int boxId = activityConfig.getWinStreakReward(round, type, userInfo.getChallengeData().getTargetUnionRank(), userInfo.getChallengeData().getWinStreakNum());
        if (boxId == 0) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_REWARD);
            return builder;
        }
        // 连胜奖励
        userInfo.getChallengeData().setReceiveWinStreakTimes(userInfo.getChallengeData().getWinStreakNum());
        // 领取奖励
        OpenGoodsBagResult openResult = TempGoodsBagMgr.getRandomGoods(boxId);
        builder.setReward(PropertyHelper.parsePropertyToString(openResult.getReward()));
        userInfo.getChallengeData().getWinStreakReward().addProperty(openResult.getReward());
        userInfo.getChallengeData().setUpdateOption();
        //随机两次奖励给客户端
        for (int i = 0; i < 2; i++) {
            OpenGoodsBagResult tempResult = TempGoodsBagMgr.getRandomGoods(boxId);
            builder.addOtherRewards(PropertyHelper.parsePropertyToString(tempResult.getReward()));
        }
        // 判断是否结算
        SeacraftSouthSeaProto.SeacraftSouthSeaChallengeResult.Builder challengeResult = settlement(userInfo, false);
        if (challengeResult != null) {
            builder.setResult(challengeResult);
        }
        builder.setBoxId(boxId);
        builder.setRet(0);
        return builder;
    }

    /**
     * 领取竞猜奖励
     *
     * @param userId
     * @param round
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaReceiveGuessRewardCrossToGameMsg.Builder receiveGuessReward(long userId, int round) {
        SeacraftSouthSeaProto.SeacraftSouthSeaReceiveGuessRewardCrossToGameMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaReceiveGuessRewardCrossToGameMsg.newBuilder();
        if (!promotionMap.containsKey(round + 1)) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_GUESS_REWARD);
            return builder;
        }
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_GUESS);
            return builder;
        }
        SeacraftSouthSeaGuessInfo guessInfo = userInfo.getBaseData().getGuessMap().get(round);
        if (guessInfo == null || guessInfo.getUnionList().size() == 0) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_GUESS);
            return builder;
        }
        if (guessInfo.isReceive()) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_RECEIVED_GUESS_REWARD);
            return builder;
        }
        int num = getGuessNum(userInfo, round);

        guessInfo.setReceive(true);
        userInfo.getBaseData().setUpdateOption();
        builder.setRound(round);
        builder.setNum(num);
        return builder;
    }

    /**
     * 获取玩家猜中的数量
     *
     * @param userInfo
     * @param round    竞猜的轮次 1开始
     * @return
     */
    public int getGuessNum(SeacraftSouthSeaCrossUserInfo userInfo, int round) {
        int num = 0;
        SeacraftSouthSeaGuessInfo guessInfo = userInfo.getBaseData().getGuessMap().get(round);
        if (guessInfo != null && guessInfo.getUnionList() != null) {
            // TODO 需要封装一下 获取 某轮 前n个联盟
            // 该轮参赛的联盟
            List<String> promotionUnionList = promotionMap.get(round);
            SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
            int guessNum = activityConfig.getGuessUnionNumMap().getOrDefault(round, 0);
            List<String> list = new ArrayList<>();
            for (String unionId : promotionUnionList) {
                SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
                SeacraftSouthSeaResultInfo resultInfo = unionInfo.getUnionData().getResultMap().get(round + 1);
                if (resultInfo != null && resultInfo.getRank() <= guessNum) {
                    list.add(unionId);
                }
            }
            for (String promotionId : list) {
                if (guessInfo.getUnionList().contains(promotionId)) {
                    num++;
                }
            }
        }
        return num;
    }


    /**
     * 玩家离开系统
     *
     * @param userId
     */
    public void exit(long userId) {
        inActivitySet.remove(userId);
    }

    /**
     * 进入竞猜
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaEnterGuessRespMsg.Builder enterGuess() {
        SeacraftSouthSeaProto.SeacraftSouthSeaEnterGuessRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaEnterGuessRespMsg.newBuilder();
        if (!isSyn.get()) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_GUESS_INFO);
            return builder;
        }
        for (Map.Entry<Integer, List<String>> entry : promotionMap.entrySet()) {
            int round = entry.getKey();
            SeacraftSouthSeaProto.SeacraftSouthSeaGuessDetail.Builder guessDetail = SeacraftSouthSeaProto.SeacraftSouthSeaGuessDetail.newBuilder();
            guessDetail.setRound(round);
            // 参赛联盟信息
            Map<String, Integer> unionMap = guessMap.get(round);
            for (String unionId : entry.getValue()) {
                SeacraftSouthSeaProto.SeacraftSouthSeaGuessUnionInfo.Builder guessUnionInfo = SeacraftSouthSeaProto.SeacraftSouthSeaGuessUnionInfo.newBuilder();
                guessUnionInfo.setUnionId(unionId);
                SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
                if (unionInfo != null) {
                    if (unionInfo.getUnionData().getUnionBaseInfo() != null) {
                        guessUnionInfo.setUnionName(unionInfo.getUnionData().getUnionBaseInfo().getUnionName());
                        guessUnionInfo.addAllUnionFlag(UnionHelper.getUnionFlag(unionInfo.getUnionData().getUnionBaseInfo()));
                    }
                    SeacraftSouthSeaResultInfo resultInfo = unionInfo.getUnionData().getResultMap().get(round);
                    if (resultInfo != null) {
                        guessUnionInfo.setRank(resultInfo.getRank());
                    }
                }
                if (unionMap != null) {
                    guessUnionInfo.setNum(unionMap.getOrDefault(unionId, 0));
                }
                guessDetail.addUnionList(guessUnionInfo);
            }
            // 猜中的数量
            Map<Integer, List<Long>> map = guessTimesMap.get(round);
            if (map != null) {
                for (Map.Entry<Integer, List<Long>> guessTimes : map.entrySet()) {
                    guessDetail.addResult(SeacraftSouthSeaProto.SeacraftSouthSeaGuessResult.newBuilder().setTimes(guessTimes.getKey()).setNum(guessTimes.getValue().size()));
                }
            }
            // 下发该轮前n名联盟
            if (promotionMap.containsKey(round)) {
                // 该轮参赛联盟
                List<String> promotionUnionList = promotionMap.get(round);
                SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
                int guessNum = activityConfig.getGuessUnionNumMap().getOrDefault(round, 0);
                for (String unionId : promotionUnionList) {
                    SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
                    SeacraftSouthSeaResultInfo resultInfo = unionInfo.getUnionData().getResultMap().get(round + 1);
                    if (resultInfo != null && resultInfo.getRank() <= guessNum) {
                        guessDetail.addPromotionUnionList(unionId);
                    }
                }
            }
            builder.addGuessInfo(guessDetail);
        }
        builder.setRet(0);
        return builder;
    }


    /**
     * 竞猜
     *
     * @param userId
     * @param unionId
     * @param serverId
     * @param round
     * @param unionList
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGuessRespMsg.Builder guess(long userId, String unionId, long serverId, int round, List<String> unionList) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGuessRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGuessRespMsg.newBuilder();
        for (String item : unionList) {
            SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(item, false);
            if (unionInfo == null) {
                // 竞猜的联盟不存在
                builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_GUESS_UNION_ID_ERROR);
                return builder;
            }
        }
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId, unionId, serverId);
        SeacraftSouthSeaGuessInfo guessInfo = userInfo.getBaseData().getGuessMap().get(round);
        if (guessInfo != null && guessInfo.getUnionList().size() > 0) {
            // 取消原来的竞猜
            guessInfo.getUnionList().forEach(e -> {
                Map<String, Integer> map = guessMap.get(round);
                int num = Math.max(0, map.getOrDefault(e, 0) - 1);
                map.put(e, num);
            });
        }
        // 加入竞猜
        unionList.forEach(e -> {
            Map<String, Integer> map = guessMap.get(round);
            if (map == null) {
                map = new ConcurrentHashMap<>();
                guessMap.put(round, map);
            }
            map.put(e, map.getOrDefault(e, 0) + 1);
        });
        userInfo.getBaseData().getGuessMap().put(round, new SeacraftSouthSeaGuessInfo(unionList));
        userInfo.getBaseData().setUpdateOption();

        // 加日志
//        SeacraftSouthSeaLogMgr.addLogSeacraftSouthSeaGuess(new LogSeacraftSouthSeaGuess(activityId, userId, round, StringUtils.listToString(unionList, ","), DateHelper.getCurrentTime()));
        CrossAutoLogMgr.add(new LogSeacraftSouthSeaGuess(activityId, userId, round, StringUtils.listToString(unionList, ","), DateHelper.getCurrentTime()));

        builder.setRet(0);
        return builder;
    }

    /**
     * 刷新玩家信息 出战次数 和挑战
     */
    private void refreshUser(SeacraftSouthSeaCrossUserInfo userInfo) {
        int curRound = getCurRound();
        if (userInfo.getBaseData().getRound() < curRound) {
            userInfo.getBaseData().setRaidAttackTimes(0);
            userInfo.getBaseData().getShipMemberMap().values().forEach(e -> {
                e.setTimes(0);
                e.setRaidTimes(0);
            });
            clearChallengeData(userInfo);
            userInfo.getBaseData().setRound(curRound);
        }
    }

    /**
     * 刷新玩家信息 楼层
     */
    private void refreshUserFloor(SeacraftSouthSeaCrossUserInfo userInfo, boolean refresh) {
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (userInfo.getBaseData().getFloor() <= 0 || userInfo.getBaseData().getFloor() > activityConfig.getFloorMap().size()) {
            if (userInfo.getBaseData().getFloor() > activityConfig.getFloorMap().size()) {
                userInfo.getBaseData().setGotBigReward(1);
            }
            userInfo.getBaseData().setFloor(1);
            refresh = true;
        }
        if (refresh) {
            int speclId = SeacraftSouthSeaMgr.random.nextInt(SeacraftSouthSeaActivityConfig.getPubGribNum());
            userInfo.getBaseData().getCellInfoList().clear();
            for (int i = 0; i < SeacraftSouthSeaActivityConfig.getPubGribNum(); i++) {
                userInfo.getBaseData().getCellInfoList().add(new SeacraftSouthSeaCellInfo(i, i == speclId));
            }
            userInfo.getBaseData().setUpdateOption();
        }
    }

    /**
     * 清楚挑战数据
     *
     * @param userInfo
     */
    public void clearChallengeData(SeacraftSouthSeaCrossUserInfo userInfo) {
        if (userInfo.getChallengeData() != null) {
            userInfo.getChallengeData().setTargetId("");
            userInfo.getChallengeData().setAttackType(0);
            userInfo.getChallengeData().setTeamType(0);
            userInfo.getChallengeData().getPatronsInfoList().clear();
            userInfo.getChallengeData().setWinStreakNum(0);
            userInfo.getChallengeData().setReceiveWinStreakTimes(0);
            userInfo.getChallengeData().setBuyBuffId(0);
            userInfo.getChallengeData().getAttackedList().clear();
            userInfo.getChallengeData().getRandomMap().clear();
            userInfo.getChallengeData().getBuffValueList().clear();
            userInfo.getChallengeData().setLockDurable(0);
            userInfo.getChallengeData().setDeductDurable(0);
            userInfo.getChallengeData().setTotalScore(0);
            userInfo.getChallengeData().setDistance(0);
            userInfo.getChallengeData().setTargetDistance(0);
            userInfo.getChallengeData().getWinStreakReward().getGoods().clear();
            userInfo.getChallengeData().setKillPatronsNum(0);
            userInfo.getBaseData().setAttackNum(userInfo.getBaseData().getAttackNum() + 1);
        }
    }

    public long getTotalBlood(SeacraftSouthSeaCrossUserInfo userInfo) {
        long totalBlood = 0;
        for (SeacraftSouthSeaLockPatronsInfo item : userInfo.getChallengeData().getPatronsInfoList()) {
            totalBlood += item.getMaxBlood();
        }
        return totalBlood;
    }

    public long getRemainBlood(SeacraftSouthSeaCrossUserInfo userInfo) {
        long remainBlood = 0;
        for (SeacraftSouthSeaLockPatronsInfo item : userInfo.getChallengeData().getPatronsInfoList()) {
            remainBlood += item.getBlood();
        }
        return remainBlood;
    }

    /**
     * 随机该联盟 可攻打的联盟
     *
     * @param unionInfo
     */
    private SeacraftSouthSeaUnionInfo randomUnion(SeacraftSouthSeaUnionInfo unionInfo) {
        // 自身排名的
        refreshUnionRank();
        List<SeacraftSouthSeaUnionInfo> canAttackUnionList = new ArrayList<>();
        // 随机出来的联盟
        SeacraftSouthSeaUnionInfo randomUnion = null;
        // 该联盟的当前排名
        int rank = getUnionRank(unionInfo, false);
        for (int i = 1; i <= SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId).getSEACRAFT_CRAFT_MATCH_NUM(); i++) {
            canAttackUnionList.addAll(getDiffRankUnionList(rank, i));
        }
        if (canAttackUnionList.size() <= 0) {
            // 扩大范围
            for (int i = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId).getSEACRAFT_CRAFT_MATCH_NUM() + 1; i <= rankList.size(); i++) {
                canAttackUnionList.addAll(getDiffRankUnionList(rank, i));
                if (canAttackUnionList.size() > 0) {
                    break;
                }
            }
        }
        if (canAttackUnionList.size() > 0) {
            randomUnion = canAttackUnionList.get(SeacraftSouthSeaMgr.random.nextInt(canAttackUnionList.size()));
        }
        return randomUnion;
    }


    /**
     * 获取参赛联盟中 与某个名次相差指定名次的 联盟集合
     * 被隐藏的船只无法被主动进攻，也无法被突袭。
     *
     * @param rank
     * @param diffRank
     * @return
     */
    public List<SeacraftSouthSeaUnionInfo> getDiffRankUnionList(int rank, int diffRank) {
        List<SeacraftSouthSeaUnionInfo> canAttackUnionList = new ArrayList<>();
        int beforeRank = rank - diffRank;
        if (beforeRank >= 1) {
            SeacraftSouthSeaUnionInfo canAttackUnion = rankList.get(beforeRank - 1);
            if (canRaidAttack(canAttackUnion, beforeRank)) {
                canAttackUnionList.add(canAttackUnion);
            }
        }
        int afterRank = rank + diffRank;
        if (afterRank <= rankList.size()) {
            SeacraftSouthSeaUnionInfo canAttackUnion = rankList.get(afterRank - 1);
            if (canRaidAttack(canAttackUnion, afterRank)) {
                canAttackUnionList.add(canAttackUnion);
            }
        }
        return canAttackUnionList;
    }

    /**
     * 是否能突袭
     *
     * @return
     */
    private boolean canRaidAttack(SeacraftSouthSeaUnionInfo attackUnion, int rank) {
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        if (!attackUnion.isDamage() && crossActivityDetail.getParam1() == attackUnion.getUnionData().getRound()) {
            if (attackUnion.isEnd(this, true)) {
                // 到达了
                if (rank <= SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId).getSEACRAFT_CRAFT_SHIP_DISPLAY_NUM()) {
                    return true;
                }
            } else {
                return true;
            }
        }
        return false;
    }


    private SeacraftSouthSeaCrossUserInfo getUserInfo(long userId) {
        return userInfoMap.get(userId);
    }


    private SeacraftSouthSeaCrossUserInfo getUserInfo(long userId, String unionId, long serverId) {
        SeacraftSouthSeaCrossUserInfo userInfo = userInfoMap.get(userId);
        if (userInfo == null) {
            synchronized (userInfoMap) {
                userInfo = userInfoMap.get(userId);
                if (userInfo == null) {
                    SeacraftSouthSeaCrossUserData userData = new SeacraftSouthSeaCrossUserData();
                    userData.setActivityId(activityId);
                    userData.setUserId(userId);
                    userData.setServerId(serverId);
                    userData.setUnionId(unionId);
                    userData.setInsertOption();

                    userInfo = new SeacraftSouthSeaCrossUserInfo(userData);
                    userInfoMap.put(userId, userInfo);
                    if (!StringUtils.isNullOrEmpty(unionId)) {
                        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, true);
                        unionInfo.getMemberMap().put(userId, userInfo);
                    }
                    // 初始化宝库信息
                    refreshUserFloor(userInfo, true);
                }
            }
        }
        return userInfo;
    }

    /**
     * 加入联盟
     *
     * @param userId
     * @param unionId
     */
    public void joinUnion(long userId, String unionId) {
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo == null || StringUtils.isNullOrEmpty(unionId)) {
            return;
        }
        if (unionId.equals(userInfo.getBaseData().getUnionId())) {
            return;
        }
        // 移除原来操作
        long now = DateHelper.getCurrentTime();
        SeacraftSouthSeaUnionInfo oldUnionInfo = getUnionInfo(userInfo.getBaseData().getUnionId(), false);
        if (oldUnionInfo != null && oldUnionInfo.getMemberMap().containsKey(userId)) {
            oldUnionInfo.getMemberMap().remove(userId);
            // 扣除 已经捐献数据
            for (Map.Entry<Integer, Long> entry : userInfo.getBaseData().getDonationShipMap().entrySet()) {
                oldUnionInfo.addDonationShip(entry.getKey(), -entry.getValue(), now);
            }
            // TODO 保护 重新计算联盟数据  线上数据修复用
            logger.info("修复捐献的联盟数据，活动id:{},userId:{},联盟id:{},原来的捐献的数据：{}", activityId, oldUnionInfo.getUnionData().getUnionId(),userId, JSON.toJSONString(oldUnionInfo.getUnionData().getDonationShipMap()));
            oldUnionInfo.getUnionData().getDonationShipMap().clear();
            for (SeacraftSouthSeaCrossUserInfo item : oldUnionInfo.getMemberMap().values()) {
                for (Map.Entry<Integer, Long> entry : item.getBaseData().getDonationShipMap().entrySet()) {
                    long oldValue = oldUnionInfo.getUnionData().getDonationShipMap().getOrDefault(entry.getKey(), 0L);
                    oldUnionInfo.getUnionData().getDonationShipMap().put(entry.getKey(), entry.getValue() + oldValue);
                }
            }
            logger.info("修复捐献的联盟数据，活动id:{},userId:{},联盟id:{},新的捐献的数据：{}", activityId, oldUnionInfo.getUnionData().getUnionId(),userId, JSON.toJSONString(oldUnionInfo.getUnionData().getDonationShipMap()));
            oldUnionInfo.getUnionData().setUpdateOption();
        }
        userInfo.getBaseData().setUnionId(unionId);
        SeacraftSouthSeaUnionInfo newUnionInfo = getUnionInfo(unionId, true);
        if (!newUnionInfo.getMemberMap().containsKey(userId)) {
            newUnionInfo.getMemberMap().put(userInfo.getBaseData().getUserId(), userInfo);
            for (Map.Entry<Integer, Long> entry : userInfo.getBaseData().getDonationShipMap().entrySet()) {
                //  有捐献记录
                if (entry.getValue() > 0) {
                    long unionOldValue = newUnionInfo.getUnionData().getDonationShipMap().getOrDefault(entry.getKey(), 0L);
                    newUnionInfo.addDonationShip(entry.getKey(), entry.getValue(), now);
                    // 加日志
//                    SeacraftSouthSeaLogMgr.addLogSeacraftSouthSeaDonation(new LogSeacraftSouthSeaDonation(activityId, userId, userInfo.getBaseData().getUnionId(), entry.getKey(), entry.getValue(), entry.getValue(), entry.getValue(), unionOldValue, unionOldValue + entry.getValue(), 2, now));
                    CrossAutoLogMgr.add(new LogSeacraftSouthSeaDonation(activityId, userId, userInfo.getBaseData().getUnionId(), entry.getKey(), entry.getValue(), entry.getValue(), entry.getValue(), unionOldValue, unionOldValue + entry.getValue(), 2, now));
                }
            }
            // TODO 保护 重新计算联盟数据  线上数据修复用
            logger.info("修复捐献的联盟数据，活动id:{},userId:{},联盟id:{},原来捐献的数据：{}", activityId, userId,unionId, JSON.toJSONString(newUnionInfo.getUnionData().getDonationShipMap()));
            newUnionInfo.getUnionData().getDonationShipMap().clear();
            for (SeacraftSouthSeaCrossUserInfo item : newUnionInfo.getMemberMap().values()) {
                for (Map.Entry<Integer, Long> donationEntry : item.getBaseData().getDonationShipMap().entrySet()) {
                    long oldValue = newUnionInfo.getUnionData().getDonationShipMap().getOrDefault(donationEntry.getKey(), 0L);
                    newUnionInfo.getUnionData().getDonationShipMap().put(donationEntry.getKey(), donationEntry.getValue() + oldValue);
                }
            }
            logger.info("修复捐献的联盟数据，活动id:{},userId:{},联盟id:{},新的捐献的数据：{}", activityId,  userId,unionId, JSON.toJSONString(newUnionInfo.getUnionData().getDonationShipMap()));
            newUnionInfo.getUnionData().setUpdateOption();
        }
    }

    /**
     * 获取联盟晋级情况
     *
     * @return
     */
    public List<SeacraftSouthSeaProto.SeacraftSouthSeaResult> getSeacraftSouthSeaResultList(String unionId) {
        List<SeacraftSouthSeaProto.SeacraftSouthSeaResult> resultList = new ArrayList<>();
        SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(unionId);
        if (unionInfo != null) {
            resultList.addAll(getUnionResultList(unionInfo));
        }
        return resultList;
    }

    /**
     * 增加buff
     */
    public Set<Integer> addBuffToTeam(SeacraftSouthSeaCrossUserInfo userInfo, int buffId, int addValue) {
        // 血量有加的门客id
        Set<Integer> set = new HashSet<>();
        userInfo.getChallengeData().setBuyBuffId(buffId);
        userInfo.getChallengeData().getBuffValueList().add(addValue);

        SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(userInfo.getBaseData().getUnionId());
        SeacraftSouthSeaShipConfig shipConfig = SeacraftSouthSeaMgr.getShipConfig(unionInfo);
        long totalBlood = 0;
        for (SeacraftSouthSeaLockPatronsInfo item : userInfo.getChallengeData().getPatronsInfoList()) {
            totalBlood += (item.getEarn() + shipConfig.getBonus());
        }
        // 回复的血量
        long addBlood = totalBlood * addValue / 100;
        // 1先扩大上限 2先尝试 把每个门客的血量回满  3再复活
        userInfo.getChallengeData().getPatronsInfoList().forEach(e -> {
            long addMaxBlood = (e.getEarn() + shipConfig.getBonus()) * addValue / 100;
            e.setMaxBlood(e.getMaxBlood() + addMaxBlood);
        });

        for (int i = userInfo.getChallengeData().getPatronsInfoList().size() - 1; i >= 0; i--) {
            SeacraftSouthSeaLockPatronsInfo patronsInfo = userInfo.getChallengeData().getPatronsInfoList().get(i);
            long diffBlood = patronsInfo.getMaxBlood() - patronsInfo.getBlood();
            if (diffBlood > 0) {
                set.add(patronsInfo.getId());
                if (addBlood > diffBlood) {
                    // 回满
                    patronsInfo.setBlood(patronsInfo.getMaxBlood());
                    addBlood -= diffBlood;
                } else {
                    patronsInfo.setBlood(patronsInfo.getBlood() + addBlood);
                    addBlood = 0;
                    break;
                }
            }
        }
        if (addBlood > 0) {
            // 复活门客
            for (int i = userInfo.getChallengeData().getPatronsInfoList().size() - 1; i >= 0; i--) {
                SeacraftSouthSeaLockPatronsInfo patronsInfo = userInfo.getChallengeData().getPatronsInfoList().get(i);
                if (patronsInfo.getBlood() <= 0) {
                    set.add(patronsInfo.getId());
                    if (addBlood > patronsInfo.getMaxBlood()) {
                        patronsInfo.setBlood(patronsInfo.getMaxBlood());
                        addBlood -= patronsInfo.getMaxBlood();
                    } else {
                        patronsInfo.setBlood(patronsInfo.getBlood() + addBlood);
                        addBlood = 0;
                        break;
                    }
                }
            }
        }
        return set;
    }


    /**
     * 查看捐献情况
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetDonationShipRespMsg.Builder getUnionDonationShipList(long userId, String unionId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetDonationShipRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetDonationShipRespMsg.newBuilder();
        if (!StringUtils.isNullOrEmpty(unionId)) {
            SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
            // 查看 联盟的捐献情况
            if (unionInfo != null) {
                builder.addAllPartInfoList(getUnionDonationShipList(unionInfo.getUnionData().getDonationShipMap()));
                // 联盟成员捐献排行
                for (SeacraftSouthSeaCrossUserInfo userInfo : unionInfo.getMemberMap().values()) {
                    long totalValue = 0;
                    for (Long value : userInfo.getBaseData().getDonationShipMap().values()) {
                        if (value > 0) {
                            totalValue += value;
                        }
                    }
                    if (totalValue > 0) {
                        SeacraftSouthSeaProto.SeacraftSouthSeaShipDonationInfo.Builder donationInfo = SeacraftSouthSeaProto.SeacraftSouthSeaShipDonationInfo.newBuilder();
                        donationInfo.setUserId(userInfo.getBaseData().getUserId());
                        String userName = CrossUserMgr.getUserName(userInfo.getBaseData().getUserId());
                        donationInfo.setUserName(userName);
                        donationInfo.setValue(totalValue);
                        builder.addDonationInfoList(donationInfo);
                    }
                }
            }
        } else {
            // 查看 自己的捐献情况
            SeacraftSouthSeaCrossUserInfo userInfo = userInfoMap.get(userId);
            if (userInfo != null) {
                builder.addAllPartInfoList(getUnionDonationShipList(userInfo.getBaseData().getDonationShipMap()));
            }
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 查看竞猜成功的玩家
     *
     * @param round
     * @param guessNum
     * @param num
     * @param pageNum
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetGuessSuccessUserRespMsg.Builder getGuessSuccessUser(int round, int guessNum, int num, int pageNum) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetGuessSuccessUserRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetGuessSuccessUserRespMsg.newBuilder();
        Map<Integer, List<Long>> timesMap = guessTimesMap.get(round);
        if (timesMap != null) {
            Set<Long> set = new HashSet<>();
            for (Map.Entry<Integer, List<Long>> entry : timesMap.entrySet()) {
                int tempGuessNum = entry.getKey();
                if (tempGuessNum >= guessNum) {
                    set.addAll(entry.getValue());
                }
            }
            for (Long userId : set) {
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
                if (userBaseInfo != null) {
                    builder.addUserList(SeacraftSouthSeaProto.SeacraftSouthSeaGuessSuccessUserInfo.newBuilder().setServerId(userBaseInfo.getServerId()).setUserName(userBaseInfo.getNickName()));
                }
            }
        }
        builder.setRet(0);
        return builder;
    }


    /**
     * 查看玩家所在的联盟排名
     *
     * @param unionId
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetUnionRankRespMsg.Builder getUnionRank(long userId, String unionId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetUnionRankRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetUnionRankRespMsg.newBuilder();
        unionId = getUserUnionId(userId, unionId);
        int rank = getUnionRank(unionId);
        builder.setRank(rank);
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
        if (unionInfo != null && unionInfo.getShipData() != null) {
            builder.setArrivalTime(unionInfo.getShipData().getEndTime());
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 查看联盟的排名
     *
     * @param unionId
     * @return
     */
    private int getUnionRank(String unionId) {
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
        if (unionInfo == null || unionInfo.getUnionData().getRound() <= 0) {
            return -1;
        }
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            return -1;
        }
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);

        if (crossActivityDetail.getParam1() > activityConfig.roundTimeList.size()) {
            // 活动已进入领奖期 排名已经固定
            return unionInfo.getUnionData().getRank();
        } else {
            // 实时去活动排名
            int rank = getUnionRank(unionInfo, true);
            if (rank == 0) {
                return -1;
            } else {
                return rank;
            }
        }
    }

    /**
     * 获取玩家所属于的联盟
     *
     * @return
     */
    private String getUserUnionId(long userId, String defaultUnionId) {
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            return "";
        }
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        if (crossActivityDetail.getParam1() > activityConfig.roundTimeList.size()) {
            // 锁榜
            if (userInfo == null) {
                return "";
            } else {
                return userInfo.getBaseData().getUnionId();
            }
        } else {
            if (userInfo == null) {
                return defaultUnionId;
            } else {
                return userInfo.getBaseData().getUnionId();
            }
        }

    }


    /**
     * 查看联盟排名列表
     *
     * @param userId
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetUnionRankListRespMsg.Builder getUnionRankList(long userId, String unionId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetUnionRankListRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetUnionRankListRespMsg.newBuilder();
        refreshUnionRank();
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        int curRound = (int) crossActivityDetail.getParam1();
        long now = DateHelper.getCurrentTime();
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        for (SeacraftSouthSeaUnionInfo item : rankList) {
            SeacraftSouthSeaProto.SeacraftSouthSeaGetUnionRankInfo.Builder unionRank = SeacraftSouthSeaProto.SeacraftSouthSeaGetUnionRankInfo.newBuilder();
            unionRank.setUnionId(item.getUnionData().getUnionId());
            unionRank.setUnionBaseInfo(UnionBasePb.parseUnionBaseTempMsg(item.getUnionData().getUnionBaseInfo()));
            if (item.getShipData() != null && activityConfig != null) {
                // 方案1 现在最新的已到达时间
//                if (item.getShipData().getEndTime() != 0) {
//                    // 显示最新的抵达时间
//                    unionRank.setArrivalTime(item.getShipData().getEndTime());
//                }else {
//                    for (int i = curRound; i > 1 ; i--) {
//                        SeacraftSouthSeaResultInfo resultInfo = item.getUnionData().getResultMap().get(i);
//                        if(resultInfo != null){
//                            unionRank.setArrivalTime(resultInfo.getArriveTime());
//                            break;
//                        }
//                    }
//                }
                // 方案2 现在预计到达时间 如果没有 显示上一轮的到达时间
//                long predictArriveTime = item.getShipPredictArriveTime(this);
//                if(predictArriveTime == 0){
//                    for (int i = curRound; i > 1 ; i--) {
//                        SeacraftSouthSeaResultInfo resultInfo = item.getUnionData().getResultMap().get(i);
//                        if(resultInfo != null){
//                            predictArriveTime = resultInfo.getArriveTime();
//                            break;
//                        }
//                    }
//                }
//                unionRank.setArrivalTime(predictArriveTime);
                // 方案3  已达到显示抵达时间  未抵达显示 航行距离 不在活动时间 显示最新一轮的信息
                if (SeacraftSouthSeaMgr.inRoundTime(activityId, curRound, now)) {
                    if (item.getUnionData().getRound() == curRound) {
                        unionRank.setArrivalTime(item.getShipData().getEndTime());
                        unionRank.setDistance(item.getDistance(this, curRound, now));
                    }
                } else {
                    SeacraftSouthSeaResultInfo resultInfo = item.getUnionData().getResultMap().get(curRound);
                    if (resultInfo != null) {
                        unionRank.setArrivalTime(resultInfo.getArriveTime());
                        unionRank.setDistance(resultInfo.getDistance());
                    }
                }
            }
            builder.addUnionRankList(unionRank);
        }
        unionId = getUserUnionId(userId, unionId);
        builder.setUnionId(unionId);
        builder.setRet(0);
        return builder;
    }

    /**
     * 查看商会南海丝路成员积分和抵达信息
     *
     * @param unionId
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetArrivalInfoRespMsg.Builder getArrivalInfo(String unionId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetArrivalInfoRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetArrivalInfoRespMsg.newBuilder();
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
        if (unionInfo != null) {
            for (SeacraftSouthSeaCrossUserInfo item : unionInfo.getMemberMap().values()) {
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(item.getBaseData().getUserId());
                if (userBaseInfo != null) {
                    builder.addUserScoreList(SeacraftSouthSeaProto.SeacraftSouthSeaUserScoreInfo.newBuilder().setUserName(userBaseInfo.getNickName()).setScore(item.getBaseData().getScore()));
                }
            }
            builder.addAllResultList(getUnionResultList(unionInfo));
        }
        builder.setRet(0);
        return builder;
    }


    /**
     * 查看船只修复情况
     *
     * @param unionId
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetFixRankRespMsg.Builder getFixRank(String unionId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetFixRankRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetFixRankRespMsg.newBuilder();
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
        if (unionInfo != null) {
            for (Map.Entry<Long, SeacraftSouthSeaFixDurableInfo> entry : unionInfo.getUnionData().getFixDurableMap().entrySet()) {
                SeacraftSouthSeaProto.SeacraftSouthSeaShipFixDurableInfo.Builder fixDurable = SeacraftSouthSeaProto.SeacraftSouthSeaShipFixDurableInfo.newBuilder();
                fixDurable.setUserId(entry.getKey());
                fixDurable.setValue(entry.getValue().getV());
                fixDurable.setTime(entry.getValue().getT());
                fixDurable.setUserName(CrossUserMgr.getUserName(entry.getKey()));
                builder.addFixInfoList(fixDurable);
            }
        }
        builder.setRet(0);
        return builder;
    }


    /**
     * 查看船只攻防信息
     *
     * @param unionId
     * @param type
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetBattleRecordRespMsg.Builder getBattleRecord(String unionId, int type) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetBattleRecordRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetBattleRecordRespMsg.newBuilder();
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
        if (unionInfo != null) {
            builder.addAllRecordList(unionInfo.getBattleRecord(this, type));
        }
        builder.setRet(0);
        return builder;
    }


    /**
     * 查看船只成员详细攻防数据
     *
     * @param type
     * @param unionId
     * @param sonType
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaGetMemberBattleDetailRespMsg.Builder getMemberBattleDetail(int type, String unionId, int sonType, String targetId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaGetMemberBattleDetailRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaGetMemberBattleDetailRespMsg.newBuilder();
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
        if (unionInfo != null) {
            builder.addAllRecordList(unionInfo.getMemberBattleDetail(this, type, sonType, targetId));
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 获取联盟 南海丝路晋级情况
     *
     * @param unionInfo
     * @return
     */
    private List<SeacraftSouthSeaProto.SeacraftSouthSeaResult> getUnionResultList(SeacraftSouthSeaUnionInfo unionInfo) {
        List<SeacraftSouthSeaProto.SeacraftSouthSeaResult> list = new ArrayList<>();
        for (Map.Entry<Integer, SeacraftSouthSeaResultInfo> entry : unionInfo.getUnionData().getResultMap().entrySet()) {
            int round = entry.getKey();
            if (round <= 1) {
                continue;
            }
            list.add(SeacraftSouthSeaProto.SeacraftSouthSeaResult.newBuilder()
                    .setRound(round).setRank(entry.getValue().getRank()).setArriveTime(entry.getValue().getArriveTime())
                    .setDistance(entry.getValue().getDistance()).build());
        }
        return list;
    }


    public int getCurRound() {
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            return 0;
        }
        ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
        if (activityInfo == null) {
            return 0;
        }
        return SeacraftSouthSeaCommonMgr.getCurRound(activityInfo, activityConfig);
    }

    /**
     * 刷新当前晋级联盟的船只数据
     */
    public void refreshCurJoinUnionShip() {
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            return;
        }
        int curRound = (int) (crossActivityDetail.getParam1());
        if (curRound <= 0 || curRound > activityConfig.roundTimeList.size()) {
            return;
        }
        long now = DateHelper.getCurrentTime();
        long roundStartTime = SeacraftSouthSeaMgr.getRoundStartTime(activityId, curRound);
        if (now == 0 || now < roundStartTime) {
            return;
        }
        for (SeacraftSouthSeaUnionInfo item : rankList) {
            if (item.getUnionData().getRound() == curRound) {
                item.initShip();
                item.resetShip(roundStartTime);
            }
        }
    }


    /**
     * 广播跑马灯
     *
     * @param userId
     * @param attackUnion
     * @param defendUnion
     * @param attackType
     * @param killNum
     * @param score
     * @param durable
     * @param goodsUseNum
     * @param time
     */
    public void broadcastSeacraftSouthSeaMarqueeInfo(long userId, SeacraftSouthSeaUnionInfo attackUnion, SeacraftSouthSeaUnionInfo defendUnion, int attackType, int killNum, int score, int durable, int goodsUseNum, long time) {
        SeacraftSouthSeaProto.BroadcastSeacraftSouthSeaRespMsg.Builder broadcast = SeacraftSouthSeaProto.BroadcastSeacraftSouthSeaRespMsg.newBuilder();
        broadcast.setType(1);
        // 船只信息
        broadcast.setSeaShipInfo(defendUnion.builderSeacraftSouthSeaShipInfo());
        // 跑马灯
        SeacraftSouthSeaProto.SeacraftSouthSeaMarqueeInfo.Builder marqueeInfo = SeacraftSouthSeaProto.SeacraftSouthSeaMarqueeInfo.newBuilder();
        marqueeInfo.setSonType(attackType);
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
        if (userBaseInfo != null) {
            marqueeInfo.setUserName(userBaseInfo.getNickName());
            marqueeInfo.setServerId(userBaseInfo.getServerId());
        }
        marqueeInfo.setUnionId(attackUnion.getUnionData().getUnionId());
        marqueeInfo.setUnionName(attackUnion.getUnionData().getUnionBaseInfo().getUnionName());
        marqueeInfo.setTargetUnionId(defendUnion.getUnionData().getUnionId());
        marqueeInfo.setTargetUnionName(defendUnion.getUnionData().getUnionBaseInfo().getUnionName());
        marqueeInfo.setTargetServerId(defendUnion.getUnionData().getUnionBaseInfo().getServerId());
        marqueeInfo.setScore(score);
        marqueeInfo.setKillNum(killNum);
        marqueeInfo.setDurable(durable);
        marqueeInfo.setGoodsUseNum(goodsUseNum);
        marqueeInfo.setTime(time);
        broadcast.setMarqueeInfo(marqueeInfo);

        lastMarqueeInfo = marqueeInfo;

        inActivitySet.forEach(e -> {
            SeacraftSouthSeaCrossUserInfo inActivityUserInfo = userInfoMap.get(e);
            if (inActivityUserInfo != null) {
                MessageHelper.sendPacket(inActivityUserInfo.getBaseData().getServerId(), e, YanQuMessageUtils.buildMessage(ClientProtocol.U_SEACRAFT_SOUTH_SEA_BROADCAST, broadcast));
            }
        });
    }

    /**
     * 广播抵达信息
     */
    public void broadcastArrivalInfo(SeacraftSouthSeaUnionInfo unionInfo, int round) {
        // 广播
        SeacraftSouthSeaResultInfo resultInfo = unionInfo.getUnionData().getResultMap().get(round);
        if (resultInfo == null) {
            return;
        }
        int rank = resultInfo.getRank();
        long arriveTime = resultInfo.getArriveTime();
        long distance = resultInfo.getDistance();
        SeacraftSouthSeaProto.BroadcastSeacraftSouthSeaRespMsg.Builder broadcast = SeacraftSouthSeaProto.BroadcastSeacraftSouthSeaRespMsg.newBuilder();
        broadcast.setType(2);
        broadcast.setResult(SeacraftSouthSeaProto.SeacraftSouthSeaResult.newBuilder()
                .setRound(round).setRank(rank).setArriveTime(arriveTime).setDistance(distance).build());
        for (SeacraftSouthSeaCrossUserInfo member : unionInfo.getMemberMap().values()) {
            if (inActivitySet.contains(member.getBaseData().getUserId())) {
                MessageHelper.sendPacket(member.getBaseData().getServerId(), member.getBaseData().getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_SEACRAFT_SOUTH_SEA_BROADCAST, broadcast));
            }
        }
    }

    /**
     * 获取玩家活动排名
     *
     * @param userId
     * @return
     */
    public int getUserRank(long userId) {
        int rank = -1;
        SeacraftSouthSeaCrossUserInfo userInfo = userInfoMap.get(userId);
        if (userInfo != null) {
            String rankType = String.valueOf(eGamePlayerEventType.SeacraftSouthSeaUserScoreRank.getValue());
//            rank = CrossYRankMgr.getUserRankNum(CrossYRankMgr.getSortUserRankList(activityId, groupId, String.valueOf(eGamePlayerEventType.SeacraftSouthSeaUserScoreRank.getValue())), userId);
            RankProto.RankListMsg.Builder rankBuilder = CrossYRankCacheMgr.getUserRankList(activityId, groupId, rankType);
            rank = CrossYRankCacheMgr.getUserRank(activityId, groupId, rankType, rankBuilder, userId);
        }
        return rank;
    }

    /**
     * 同步玩家小队信息
     *
     * @param userInfo
     * @param teamInfoList
     */
    private void synUserTeamInfo(SeacraftSouthSeaCrossUserInfo userInfo, List<SeacraftSouthSeaProto.SeacraftSouthSeaLockTeamInfo> teamInfoList) {
        long now = DateHelper.getCurrentTime();
        for (SeacraftSouthSeaProto.SeacraftSouthSeaLockTeamInfo item : teamInfoList) {
            SeacraftSouthSeaTeamInfo teamInfo = new SeacraftSouthSeaTeamInfo();
            for (SeacraftSouthSeaProto.SeacraftSouthSeaPatronsEntity patronsEntity : item.getPatronsList()) {
                teamInfo.getTeamList().add(parseSouthSeaPatronsInfo(patronsEntity));
            }
            userInfo.getBaseData().getShipMemberMap().put(item.getType(), teamInfo);
            userInfo.getBaseData().setUpdateOption();
            // 船员小队组队日志
            addLogSeacraftSouthSeaTeam(userInfo, teamInfo, item.getType(), now);
        }
    }

    /**
     * 是否可以领取连胜奖励
     *
     * @param userInfo
     * @return
     */
    public boolean canRecWinStreakReward(SeacraftSouthSeaCrossUserInfo userInfo) {
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig != null) {
            if (userInfo.getChallengeData().getWinStreakNum() != 0 && userInfo.getChallengeData().getWinStreakNum() != userInfo.getChallengeData().getReceiveWinStreakTimes() &&
                    userInfo.getChallengeData().getWinStreakNum() % activityConfig.getSEACRAFT_CRAFT_REWARD_COMBONUM() == 0) {
                // 到了可以领取连胜奖励的档位
                return true;
            }
        }
        return false;
    }

    /**
     * 挑战结算
     *
     * @param attacker
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaChallengeResult.Builder settlement(SeacraftSouthSeaCrossUserInfo attacker, boolean forceSettlement) {
        SeacraftSouthSeaProto.SeacraftSouthSeaChallengeResult.Builder challengeResult = null;

        SeacraftSouthSeaUnionInfo attackUnion = unionInfoMap.get(attacker.getBaseData().getUnionId());
        SeacraftSouthSeaUnionInfo targetUnion = unionInfoMap.get(attacker.getChallengeData().getTargetId());
        boolean isWin = isKillAll(attacker, targetUnion);
        if (forceSettlement || (!canRecWinStreakReward(attacker) && isWin)) {
            long time = DateHelper.getCurrentTime();
            attackUnion.addRecord(0, attacker.getChallengeData().getAttackType(), attacker.getBaseData().getUserId(), attacker.getChallengeData().getTargetId(), attacker.getChallengeData().getWinStreakNum(), attacker.getChallengeData().getTotalScore(), attacker.getChallengeData().getDeductDurable(), 0, time, 0, 0, 0);
            targetUnion.addRecord(1, attacker.getChallengeData().getAttackType(), attacker.getBaseData().getUserId(), attacker.getBaseData().getUnionId(), attacker.getChallengeData().getWinStreakNum(), attacker.getChallengeData().getTotalScore(), attacker.getChallengeData().getDeductDurable(), 0, time, 0, 0, 0);

            // 加进攻 细节
            addBattleDetail(attackUnion, attacker.getBaseData().getUserId(), targetUnion, attacker.getChallengeData().getAttackType(), attacker.getChallengeData().getDeductDurable(), time);

            challengeResult = SeacraftSouthSeaProto.SeacraftSouthSeaChallengeResult.newBuilder();
            challengeResult.setTotalScore(attacker.getChallengeData().getTotalScore());
            challengeResult.setTotalDurable(attacker.getChallengeData().getDeductDurable());
            challengeResult.setKillNum(attacker.getChallengeData().getAttackedList().size());
            challengeResult.setWinStreakReward(PropertyHelper.parsePropertyToString(attacker.getChallengeData().getWinStreakReward()));
            challengeResult.setWinStreakNum(attacker.getChallengeData().getWinStreakNum());
            challengeResult.setUnionName(targetUnion.getUnionData().getUnionBaseInfo().getUnionName());
            challengeResult.setIsWin(isWin);
            challengeResult.setKillPatronsNum(attacker.getChallengeData().getKillPatronsNum());
            SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);

            if (challengeResult.getTotalDurable() > 0 && challengeResult.getKillNum() >= activityConfig.getSEACRAFT_CRAFT_KILL_REPORT()) {
                broadcastSeacraftSouthSeaMarqueeInfo(attacker.getBaseData().getUserId(), attackUnion, targetUnion, attacker.getChallengeData().getAttackType(), challengeResult.getKillNum(), challengeResult.getTotalScore(), challengeResult.getTotalDurable(), 0, time);
            }
            String reward = null;
            if (isKillAll(attacker, targetUnion)) {
                reward = activityConfig.battleRewardList.get(0);
            } else {
                reward = activityConfig.battleRewardList.get(1);
            }
            // 计算获得的勋章奖励
            int medalNum = getMedalNum(activityConfig, attacker);
            challengeResult.setGetMedalNum(medalNum);
            challengeResult.setBattleReward(reward);
            clearChallengeData(attacker);
        }

        return challengeResult;
    }

    /**
     * 是否全歼联盟玩家
     *
     * @return
     */
    public boolean isKillAll(SeacraftSouthSeaCrossUserInfo attacker, SeacraftSouthSeaUnionInfo targetUnion) {
        return attacker.getChallengeData().getAttackedList().size() >= targetUnion.getMemberMap().size();
    }

    /**
     * 获得勋章的数量
     *
     * @return
     */
    public int getMedalNum(SeacraftSouthSeaActivityConfig activityConfig, SeacraftSouthSeaCrossUserInfo attacker) {
        int medalNum = 0;
        if (attacker.getChallengeData() != null) {
            if (attacker.getChallengeData().getAttackType() == 0) {
                medalNum = activityConfig.getSEACRAFT_CRAFT_CHARGE_SCORE();
            } else {
                // 本次进攻消耗的进攻道具数量
                SeacraftSouthSeaTeamInfo seaTeamInfo = attacker.getBaseData().getShipMemberMap().get(attacker.getChallengeData().getTeamType());
                // 判断消耗数量
                int consumeNum = 0;
                if (activityConfig.attackItemCostList.size() > seaTeamInfo.getTimes() - 1) {
                    consumeNum = activityConfig.attackItemCostList.get(seaTeamInfo.getTimes() - 1);
                }
                medalNum = activityConfig.attackScoreList.get(0) + activityConfig.attackScoreList.get(1) * consumeNum;
            }
        }
        return medalNum;
    }

    /**
     * 领取排行榜奖励
     *
     * @param userId
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaReceiveUnionRankCrossToGameMsg.Builder receiveUnionRank(long userId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaReceiveUnionRankCrossToGameMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaReceiveUnionRankCrossToGameMsg.newBuilder();
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_CONFIG);
            return builder;
        }
        int curRound = (int) (crossActivityDetail.getParam1());
        if (curRound <= activityConfig.roundTimeList.size()) {
            // 未结算
            builder.setRet(GameErrorCode.E_ACTIVITY_NO_IN_GET_REWARD_TIME);
            return builder;
        }
        int rank = -1;
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo != null) {
            SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(userInfo.getBaseData().getUnionId(), false);
            if (unionInfo != null && unionInfo.getUnionData().getRound() > 0 && unionInfo.getUnionData().getMemberSet().contains(userId)) {
                rank = unionInfo.getUnionData().getRank();
                builder.setMasterId(unionInfo.getUnionData().getUnionBaseInfo().getMasterUserId());
                builder.setUnionId(unionInfo.getUnionData().getUnionId());
                //暂时，荣誉点，后续版本优化
                ActivityInfo activityInfo = ActivityMgr.getActivityInfoMayLoadDB(activityId);
                int lowestRank = 1;
                lowestRank = CrossUnionHonorsActivityMgr.getLowestRewardRank(activityInfo.getServerIdList().size(), eHonorsActivityType.UNION_HONORS_SEA_CRAFT);
                if (activityInfo != null) {
                    //拿出头n名
                    List<String> top = getRankTop(lowestRank);
                    if (top != null) {
                        if (!top.isEmpty()) {
//                            CrossUnionHonorsActivityMgr.add(activityId, top, activityInfo.getType(), activityInfo.getChildType(), activityInfo.getServerIdList(),userInfo.getBaseData().getServerId());
                        }
                    }
                }
            }
        }
        builder.setActivityId(activityId);
        builder.setRank(rank);
        builder.setRet(0);
        return builder;
    }


    /**
     * 请求功勋酒馆数据
     *
     * @param userId
     * @return
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaPubRespMsg.Builder getPub(long userId) {
        SeacraftSouthSeaProto.SeacraftSouthSeaPubRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaPubRespMsg.newBuilder();
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_GRIB);
            return builder;
        }
        refreshUserFloor(userInfo, false);
        for (SeacraftSouthSeaCellInfo item : userInfo.getBaseData().getCellInfoList()) {
            SeacraftSouthSeaProto.SeacraftSouthSeaCellData.Builder cellBuilder = SeacraftSouthSeaProto.SeacraftSouthSeaCellData.newBuilder();
            if (item.isOpen()) {
                cellBuilder.setReward(item.getReward());
            }
            cellBuilder.setOpen(item.isOpen());
            builder.addCell(cellBuilder);
        }
        builder.setGotBigReward(userInfo.getBaseData().getGotBigReward());
        builder.setFloor(userInfo.getBaseData().getFloor());
        builder.setRet(0);
        return builder;
    }

    /**
     * 功勋酒馆挖宝
     *
     * @param userId
     * @param index
     */
    public SeacraftSouthSeaProto.SeacraftSouthSeaOpenPubRespMsg.Builder openPub(long userId, int floor, int index) {
        SeacraftSouthSeaProto.SeacraftSouthSeaOpenPubRespMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaOpenPubRespMsg.newBuilder();
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_NO_GRIB);
            return builder;
        }
        refreshUserFloor(userInfo, false);
        if (userInfo.getBaseData().getFloor() != floor) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_FLOOR_ERROR);
            return builder;
        }
        if (index < 0 || index + 1 > userInfo.getBaseData().getCellInfoList().size()) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_ID_ERROR);
            return builder;
        }
        SeacraftSouthSeaCellInfo cellInfo = userInfo.getBaseData().getCellInfoList().get(index);
        if (cellInfo == null) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_ID_ERROR);
            return builder;
        }
        if (cellInfo.isOpen()) {
            builder.setRet(GameErrorCode.E_SEACRAFT_SOUTH_SEA_ACTIVITY_GRID_IS_OPEN);
            return builder;
        }
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        SeacraftSouthSeaFloorConfig floorConfig = activityConfig.getFloorMap().get(floor);
        Property reward = new Property();
        boolean refresh = false;
        if (cellInfo.isSpecl()) {
            reward.addProperty(PropertyHelper.parseStringToProperty(floorConfig.getSpecialRewardStr()));
            if (floorConfig.getSpecialRewardList().size() > 0) {
                Property randomReward = RandomWeightConfigHelper.getPropertyWeightItem(floorConfig.getSpecialRewardList());
                reward.addProperty(randomReward);
            }
            refresh = true;
        } else {
            Property randomReward = RandomWeightConfigHelper.getPropertyWeightItem(floorConfig.getWeightList());
            reward.addProperty(randomReward);
        }
        cellInfo.setOpen(true);
        String rewardStr = PropertyHelper.parsePropertyToString(reward);
        cellInfo.setReward(rewardStr);
        userInfo.getBaseData().setUpdateOption();
        if (refresh) {
            userInfo.getBaseData().setFloor(userInfo.getBaseData().getFloor() + 1);
            refreshUserFloor(userInfo, true);
        }
        builder.setFloor(userInfo.getBaseData().getFloor());
        builder.setReward(rewardStr);
        builder.setSpecial(refresh);
        builder.setRet(0);
        return builder;
    }


    /**
     * 查看联盟加速榜
     *
     * @param unionId
     * @return
     */
    public List<SeacraftSouthSeaProto.SeacraftSouthSeaSpeedUpRecordInfo> getSpeedUpRecord(String unionId) {
        List<SeacraftSouthSeaProto.SeacraftSouthSeaSpeedUpRecordInfo> list = new ArrayList<>();
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
        if (unionInfo != null) {
            for (SeacraftSouthSeaCrossUserInfo item : unionInfo.getMemberMap().values()) {
                if (item.getBaseData().getUseSpeedUpInfoMap().size() > 0) {
                    SeacraftSouthSeaProto.SeacraftSouthSeaSpeedUpRecordInfo.Builder recordInfo = SeacraftSouthSeaProto.SeacraftSouthSeaSpeedUpRecordInfo.newBuilder();
                    UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(item.getBaseData().getUserId());
                    if (userBaseInfo != null) {
                        recordInfo.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
                    }
                    recordInfo.setUserId(item.getBaseData().getUserId());
                    for (SeacraftSouthSeaUseSpeedUpInfo speedUpInfo : item.getBaseData().getUseSpeedUpInfoMap().values()) {
                        SeacraftSouthSeaProto.SeacraftSouthSeaUseSpeedUpPropInfo.Builder useSpeedUpPropInfo = SeacraftSouthSeaProto.SeacraftSouthSeaUseSpeedUpPropInfo.newBuilder();
                        useSpeedUpPropInfo.setPropId(speedUpInfo.getPropId());
                        useSpeedUpPropInfo.setNum(speedUpInfo.getNum());
                        useSpeedUpPropInfo.setTotalValue(speedUpInfo.getTotalValue());
                        recordInfo.addUseSpeedUpPropInfoList(useSpeedUpPropInfo);
                    }
                    list.add(recordInfo.build());
                }
            }
        }
        return list;
    }

    /**
     * 获取当前船只加速详情
     *
     * @param unionId
     * @return
     */
    public List<SeacraftSouthSeaProto.SeacraftSouthSeaSpeedUpInfo> getCurSpeedUpDetail(String unionId) {
        List<SeacraftSouthSeaProto.SeacraftSouthSeaSpeedUpInfo> list = new ArrayList<>();
        SeacraftSouthSeaUnionInfo unionInfo = getUnionInfo(unionId, false);
        if (unionInfo != null && unionInfo.getShipData() != null) {
            for (SeacraftSouthSeaCurSpeedInfo item : unionInfo.getSpeedRecordList()) {
                SeacraftSouthSeaProto.SeacraftSouthSeaSpeedUpInfo.Builder speedInfo = SeacraftSouthSeaProto.SeacraftSouthSeaSpeedUpInfo.newBuilder();
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(item.getId());
                if (userBaseInfo != null) {
                    speedInfo.setUserName(userBaseInfo.getNickName());
                }
                speedInfo.setSpeed(item.getV());
                speedInfo.setEndTime(item.getEndT());
                list.add(speedInfo.build());
            }
        }
        return list;
    }


    /**
     * 同步 门客
     *
     * @param userPatronsInfoList
     */
    public void synUserInfo(List<SeacraftSouthSeaProto.SeacraftSouthSeaSynUserPatronsInfo> userPatronsInfoList) {
        long now = DateHelper.getCurrentTime();
        for (SeacraftSouthSeaProto.SeacraftSouthSeaSynUserPatronsInfo item : userPatronsInfoList) {
            long userId = item.getUserId();
            List<SeacraftSouthSeaProto.SeacraftSouthSeaPatronsEntity> patronsList = item.getPatronsListList();
            SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
            if (userInfo == null) {
                return;
            }
            // 遍历改变的门客 更改或替换  然后再遍历
            for (SeacraftSouthSeaProto.SeacraftSouthSeaPatronsEntity patronsEntity : patronsList) {
                PatronsInfo patronsInfoConfig = PatronsMgr.getPatronsInfoMap().get(patronsEntity.getPatronsId());
                SeacraftSouthSeaTeamInfo teamInfo = userInfo.getBaseData().getShipMemberMap().get(patronsInfoConfig.getOccupation());
                // 改变数值
                boolean change = false;
                // 替换门客
                boolean replace = false;
                for (SeacraftSouthSeaPatronsInfo patronsInfo : teamInfo.getTeamList()) {
                    if (patronsInfo.getId() == patronsEntity.getPatronsId()) {
                        patronsInfo.setLv(patronsEntity.getLevel());
                        patronsInfo.setStageLv(patronsEntity.getStageLv());
                        patronsInfo.setSkinId(patronsEntity.getSkinId());
                        patronsInfo.setEarn(patronsEntity.getEarn());
                        patronsInfo.setPromotionId(patronsEntity.getPromotionId());
                        patronsInfo.setAddPlus(patronsEntity.getAddPlus());
                        change = true;
                        break;
                    }
                }
                if (!change && teamInfo.getTeamList().size() < SeacraftSouthSeaActivityConfig.getTeamNum()) {
                    teamInfo.getTeamList().add(parseSouthSeaPatronsInfo(patronsEntity));
                    change = true;
                    replace = true;
                }
                if (!change) {
                    Iterator<SeacraftSouthSeaPatronsInfo> iterator = teamInfo.getTeamList().iterator();
                    while (iterator.hasNext()) {
                        SeacraftSouthSeaPatronsInfo patronsInfo = iterator.next();
                        // 比较战斗力
                        long value1 = patronsInfo.getEarn() * (1000 + patronsInfo.getAddPlus()) / 1000;
                        long value2 = patronsEntity.getEarn() * (1000 + patronsEntity.getAddPlus()) / 1000;
                        if (value1 < value2 || (value1 == value2 && patronsInfo.getId() < patronsEntity.getPatronsId())) {
                            // 移除最后一个 并 加入一个
                            teamInfo.getTeamList().remove(teamInfo.getTeamList().size() - 1);
                            //
                            teamInfo.getTeamList().add(parseSouthSeaPatronsInfo(patronsEntity));
                            change = true;
                            replace = true;
                            break;
                        }
                    }
                }
                if (change) {
                    teamInfo.getTeamList().sort((t1, t2) -> {
                        return SeacraftSouthSeaCommonMgr.comparator(t1.getId(), t1.getEarn(), t1.getAddPlus(), t2.getId(), t2.getEarn(), t2.getAddPlus());
                    });
                    if (replace) {
                        addLogSeacraftSouthSeaTeam(userInfo, teamInfo, patronsInfoConfig.getOccupation(), now);
                    }
                }
            }
        }
    }


    public void addLogSeacraftSouthSeaTeam(SeacraftSouthSeaCrossUserInfo userInfo, SeacraftSouthSeaTeamInfo teamInfo, int type, long now) {
        // 加变动日志
        List<Integer> patronsIdList = new ArrayList<>();
        long defendValue = 0;
        long addPlus = SeacraftSouthSeaActivity.getTeamAddBuff(teamInfo);
        long attackValue = 0;
        for (SeacraftSouthSeaPatronsInfo patronsInfo : teamInfo.getTeamList()) {
            patronsIdList.add(patronsInfo.getId());
            defendValue += patronsInfo.getEarn();
        }
        attackValue = defendValue * addPlus / 1000L;
//        SeacraftSouthSeaLogMgr.addLogSeacraftSouthSeaTeam(new LogSeacraftSouthSeaTeam(activityId, userInfo.getBaseData().getUnionId(), type, userInfo.getBaseData().getUserId(), StringUtils.listToString(patronsIdList, ","), defendValue, attackValue, now));
        CrossAutoLogMgr.add(new LogSeacraftSouthSeaTeam(activityId, userInfo.getBaseData().getUnionId(), type, userInfo.getBaseData().getUserId(), StringUtils.listToString(patronsIdList, ","), defendValue, attackValue, now));
    }

    public Map<String, SeacraftSouthSeaUnionInfo> getUnionInfoMap() {
        return unionInfoMap;
    }

    /**
     * 获取玩家积分
     *
     * @param userId
     * @return
     */
    public int getUserScore(long userId) {
        SeacraftSouthSeaCrossUserInfo userInfo = getUserInfo(userId);
        if (userInfo != null) {
            return userInfo.getBaseData().getScore();
        }
        return 0;
    }

    /**
     * 购买buff的值
     *
     * @param userInfo
     * @return
     */
    public int getBuyBuffValue(SeacraftSouthSeaCrossUserInfo userInfo) {
        int totalValue = 0;
        if (userInfo.getChallengeData() != null) {
            for (Integer value : userInfo.getChallengeData().getBuffValueList()) {
                totalValue += value;
            }
        }
        return totalValue;
    }

    /**
     * 广播船只信息
     */
    public void broadcastShipInfoToInActivityUser(SeacraftSouthSeaUnionInfo unionInfo, List<Long> excludeList) {
        SeacraftSouthSeaProto.BroadcastSeacraftSouthSeaRespMsg.Builder broadcast = SeacraftSouthSeaProto.BroadcastSeacraftSouthSeaRespMsg.newBuilder();
        broadcast.setType(0);
        broadcast.setSeaShipInfo(unionInfo.builderSeacraftSouthSeaShipInfo());
        for (Long userId : inActivitySet) {
            if (excludeList == null || !excludeList.contains(userId)) {
                UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
                if (userBaseInfo != null) {
                    MessageHelper.sendPacket(userBaseInfo.getServerId(), userId, YanQuMessageUtils.buildMessage(ClientProtocol.U_SEACRAFT_SOUTH_SEA_BROADCAST, broadcast));
                }
            }
        }
    }


    public SeacraftSouthSeaProto.SeacraftSouthSeaShipRecordInfo.Builder builderSeacraftSouthSeaShipRecordInfo(SeacraftSouthSeaCrossRecordData item) {
        SeacraftSouthSeaProto.SeacraftSouthSeaShipRecordInfo.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaShipRecordInfo.newBuilder();
        builder.setMasterType(item.getMasterType());
        builder.setSonType(item.getSonType());
        builder.setUserId(item.getUserId());
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(item.getUserId());
        if (userBaseInfo != null) {
            builder.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        }
        SeacraftSouthSeaCrossUserInfo userInfo = userInfoMap.get(item.getUserId());
        if (userInfo != null) {
            SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(userInfo.getBaseData().getUnionId());
            if (unionInfo != null) {
                builder.setOwnUnionName(unionInfo.getUnionData().getUnionBaseInfo().getUnionName());
            }
        }
        if (!StringUtils.isNullOrEmpty(item.getTargetId())) {
            // 目标商会
            SeacraftSouthSeaUnionInfo unionInfo = unionInfoMap.get(item.getTargetId());
            if (unionInfo != null) {
                builder.setUnionName(unionInfo.getUnionData().getUnionBaseInfo().getUnionName());
            }
        }
        builder.setMasterType(item.getMasterType());
        builder.setKillNum(item.getKillNum());
        builder.setScore(item.getScore());
        builder.setDurable(item.getDurable());
        builder.setGoodsUseNum(item.getGoodsUseNum());
        builder.setTime(item.getTime());
        builder.setPropId(item.getPropId());
        builder.setSpeed(item.getSpeed());
        builder.setContinueTime(item.getContinueTime());
        return builder;
    }

    private static SeacraftSouthSeaPatronsInfo parseSouthSeaPatronsInfo(SeacraftSouthSeaProto.SeacraftSouthSeaPatronsEntity item) {
        SeacraftSouthSeaPatronsInfo patronsInfo = new SeacraftSouthSeaPatronsInfo();
        patronsInfo.setId(item.getPatronsId());
        patronsInfo.setLv(item.getLevel());
        patronsInfo.setStageLv(item.getStageLv());
        patronsInfo.setSkinId(item.getSkinId());
        patronsInfo.setEarn(item.getEarn());
        patronsInfo.setPromotionId(item.getPromotionId());
        patronsInfo.setAddPlus(item.getAddPlus());
        return patronsInfo;
    }

    public SeacraftSouthSeaProto.SeacraftSouthSeaChallengeInfo.Builder builderSeacraftSouthSeaChallengeInfo(SeacraftSouthSeaCrossUserInfo userInfo) {
        SeacraftSouthSeaProto.SeacraftSouthSeaChallengeInfo.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaChallengeInfo.newBuilder();
        builder.setTargetUnionId(userInfo.getChallengeData().getTargetId());
        SeacraftSouthSeaUnionInfo targetUnionInfo = unionInfoMap.get(userInfo.getChallengeData().getTargetId());
        if (targetUnionInfo != null) {
            UnionBaseInfo unionBaseInfo = targetUnionInfo.getUnionData().getUnionBaseInfo();
            builder.addAllUnionFlag(UnionHelper.getUnionFlag(unionBaseInfo));
            builder.setMemberNum(targetUnionInfo.getUnionData().getMemberSet().size());
            builder.setUnionHonerPoint(targetUnionInfo.getUnionData().getUnionBaseInfo().getHonors());
        }
        builder.setLockDurable(userInfo.getChallengeData().getLockDurable());
        builder.setDeductDurable(userInfo.getChallengeData().getDeductDurable());
        builder.setTeamType(userInfo.getChallengeData().getTeamType());
        // 小队门客赚钱 (出战后锁定)
        long lockEarn = 0;
        if (userInfo.getChallengeData().getTeamType() > 0) {
            for (SeacraftSouthSeaLockPatronsInfo item : userInfo.getChallengeData().getPatronsInfoList()) {
                lockEarn += item.getEarn();
            }
        }
        List<SeacraftSouthSeaProto.SeacraftSouthSeaPatronsInfo> list = builderSeacraftSouthSeaPatronsInfoList(userInfo);
        if (list != null && list.size() > 0) {
            builder.addAllPatronsInfoList(list);
        }
        builder.setWinStreakNum(userInfo.getChallengeData().getWinStreakNum());
        builder.setCanRecWinStreakReward(canRecWinStreakReward(userInfo));
        builder.setBuffId(userInfo.getChallengeData().getBuyBuffId());
        builder.setAttackedNum(userInfo.getChallengeData().getAttackedList().size());
        builder.setBuffValue(getBuyBuffValue(userInfo));
        builder.setLockEarn(lockEarn);
        builder.setAttackedUnionNum(userInfo.getBaseData().getAttackNum());
        builder.setTargetUnionRank(userInfo.getChallengeData().getTargetUnionRank());
        for (Map.Entry<Long, Integer> entry : userInfo.getChallengeData().getRandomMap().entrySet()) {
            SeacraftSouthSeaProto.SeacraftSouthSeaTargetInfo.Builder targetInfo = SeacraftSouthSeaProto.SeacraftSouthSeaTargetInfo.newBuilder();
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(entry.getKey());
            PlayerProto.PlayerDataTempMsg.Builder player = PlayerProto.PlayerDataTempMsg.newBuilder();
            if (userBaseInfo != null) {
                player.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            }
            player.setUserId(entry.getKey());
            targetInfo.setTargetInfo(player);
            targetInfo.setTeamType(entry.getValue());
            builder.addTargetInfoList(targetInfo);
        }
        builder.setChallengeType(userInfo.getChallengeData().getAttackType());
        return builder;
    }

    /**
     * 获取玩家挑战数据的门客
     *
     * @param userInfo
     * @return
     */
    public static List<SeacraftSouthSeaProto.SeacraftSouthSeaPatronsInfo> builderSeacraftSouthSeaPatronsInfoList(SeacraftSouthSeaCrossUserInfo userInfo) {
        List<SeacraftSouthSeaProto.SeacraftSouthSeaPatronsInfo> list = new ArrayList<>();
        if (userInfo != null && userInfo.getChallengeData() != null) {
            for (SeacraftSouthSeaLockPatronsInfo item : userInfo.getChallengeData().getPatronsInfoList()) {
                list.add(SeacraftSouthSeaProto.SeacraftSouthSeaPatronsInfo.newBuilder().setBlood(item.getBlood()).setMaxBlood(item.getMaxBlood()).setAddPlus(item.getAddPlus()).setPatronsId(item.getId()).build());
            }
        }
        return list;
    }

    public SeacraftSouthSeaProto.SeacraftSouthSeaBattleRecordInfo.Builder builderSeacraftSouthSeaBattleRecordInfo(SeacraftSouthSeaBattleDetailData item) {
        SeacraftSouthSeaProto.SeacraftSouthSeaBattleRecordInfo.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaBattleRecordInfo.newBuilder();
        builder.setType(item.getMasterType());
        builder.setUnionUid(item.getTargetUnionId());
        SeacraftSouthSeaUnionInfo targetUnionInfo = unionInfoMap.get(item.getTargetUnionId());
        if (targetUnionInfo != null && targetUnionInfo.getUnionData().getUnionBaseInfo() != null) {
            builder.setUnionInfo(UnionBasePb.parseUnionBaseTempMsg(targetUnionInfo.getUnionData().getUnionBaseInfo()));
        }
        builder.setSuddenAttack(calTotalDamage(item.getRaidAttackMap()));
        builder.setAttack(calTotalDamage(item.getAttackMap()));
        builder.setFire(calTotalDamage(item.getUseGoodMap()));
        builder.setTime(item.getTime());
        return builder;
    }

    /**
     * 计算总伤害
     *
     * @param detailData
     * @return
     */
    private long calTotalDamage(SeacraftSouthSeaBattleDetailData detailData) {
        long totalValue = 0;
        totalValue += calTotalDamage(detailData.getAttackMap());
        totalValue += calTotalDamage(detailData.getRaidAttackMap());
        totalValue += calTotalDamage(detailData.getUseGoodMap());
        detailData.setTotalDamage(totalValue);
        return totalValue;
    }

    private long calTotalDamage(Map<Long, SeacraftSouthSeaBattleDetailInfo> detailInfoMap) {
        long totalValue = 0;
        for (SeacraftSouthSeaBattleDetailInfo item : detailInfoMap.values()) {
            totalValue += item.getV();
        }
        return totalValue;
    }


    public List<SeacraftSouthSeaProto.SeacraftSouthSeaMemberBattleDetailInfo> builderSeacraftSouthSeaMemberBattleDetailInfoList(Map<Long, SeacraftSouthSeaBattleDetailInfo> map) {
        List<SeacraftSouthSeaProto.SeacraftSouthSeaMemberBattleDetailInfo> list = new ArrayList<>();
        for (Map.Entry<Long, SeacraftSouthSeaBattleDetailInfo> entry : map.entrySet()) {
            if (entry.getValue().getV() <= 0) {
                continue;
            }
            SeacraftSouthSeaProto.SeacraftSouthSeaMemberBattleDetailInfo.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaMemberBattleDetailInfo.newBuilder();
            builder.setUserName(CrossUserMgr.getUserName(entry.getKey()));
            builder.setServerId(CrossUserMgr.getServerIdByUserId(entry.getKey()));
            builder.setValue(entry.getValue().getV());
            builder.setTime(entry.getValue().getT());
            list.add(builder.build());
        }
        return list;
    }


    /**
     * 获取小队的天赋加成
     *
     * @param teamInfo
     * @return
     */
    public static long getTeamAddBuff(SeacraftSouthSeaTeamInfo teamInfo) {
        int addPlus = 0;
        for (SeacraftSouthSeaPatronsInfo item : teamInfo.getTeamList()) {
            addPlus += item.getAddPlus();
        }
        return addPlus;
    }

    public int getActivityId() {
        return activityId;
    }

    public SeacraftSouthSeaProto.SeacraftSouthSeaSynPromotionUnionCrossToGameMsg.Builder getPromotionUnion() {
        SeacraftSouthSeaProto.SeacraftSouthSeaSynPromotionUnionCrossToGameMsg.Builder builder = SeacraftSouthSeaProto.SeacraftSouthSeaSynPromotionUnionCrossToGameMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setGroupId(groupId);
        for (Map.Entry<Integer, List<String>> entry : promotionMap.entrySet()) {
            builder.addPromotionList(SeacraftSouthSeaProto.SeacraftSouthSeaPromotionUnionMsg.newBuilder().setRound(entry.getKey())
                    .addAllUnionId(entry.getValue()));
        }
        return builder;
    }

    public Map<Long, SeacraftSouthSeaCrossUserInfo> getUserInfoMap() {
        return userInfoMap;
    }

    public static List<SeacraftSouthSeaProto.SeacraftSouthSeaShipPartInfo> getUnionDonationShipList(Map<Integer, Long> donationShipMap) {
        List<SeacraftSouthSeaProto.SeacraftSouthSeaShipPartInfo> list = new ArrayList<>();
        for (Map.Entry<Integer, Long> entry : donationShipMap.entrySet()) {
            if (entry.getValue() > 0) {
                list.add(SeacraftSouthSeaProto.SeacraftSouthSeaShipPartInfo.newBuilder().setType(entry.getKey()).setValue(entry.getValue()).build());
            }
        }
        return list;
    }

    public List<SeacraftSouthSeaUnionInfo> getRankList() {
        return rankList;
    }

    /**
     * 本轮晋级人数
     *
     * @return
     */
    public int thisRoundPromotionNum() {
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);

        // 找到对应 的晋级名单
        return SeacraftSouthSeaCommonMgr.thisRoundPromotionNum((int) (crossActivityDetail.getParam1()), activityConfig);
    }


    public Map<Integer, List<String>> getPromotionMap() {
        return promotionMap;
    }

    /**
     * 获取当前轮次晋级的联盟
     *
     * @return
     */
    public List<SeacraftSouthSeaUnionInfo> getCurJoiningList() {
        List<SeacraftSouthSeaUnionInfo> list = new ArrayList<>();
        int promotionNum = thisRoundPromotionNum();
        for (int i = 0; i < promotionNum; i++) {
            list.add(rankList.get(i));
        }
        return list;
    }

    /**
     * 获取当前调整的小队血量
     *
     * @param userInfo
     * @return
     */
    public long getTeamBlood(SeacraftSouthSeaCrossUserInfo userInfo) {
        long teamBlood = 0;
        if (userInfo.getChallengeData() != null) {
            for (SeacraftSouthSeaLockPatronsInfo item : userInfo.getChallengeData().getPatronsInfoList()) {
                if (item.getBlood() > 0) {
                    teamBlood += item.getBlood();
                }
            }
        }
        return teamBlood;
    }

    /**
     * 刷新所有晋级的船只
     */
    public List<String> refreshAllPromotionShip() {
        List<String> promotionList = new ArrayList<>();
        int promotionNum = thisRoundPromotionNum();
        long now = DateHelper.getCurrentTime();
        for (int i = 0; i < promotionNum; i++) {
            if (rankList.size() <= i) {
                break;
            }
            SeacraftSouthSeaUnionInfo unionInfo = rankList.get(i);
            unionInfo.refreshShip(this, now);
        }
        refreshUnionRank();

        for (int i = 0; i < promotionNum; i++) {
            if (rankList.size() <= i) {
                break;
            }
            SeacraftSouthSeaUnionInfo unionInfo = rankList.get(i);
            promotionList.add(unionInfo.getUnionData().getUnionId());
        }
        return promotionList;
    }


    /**
     * 加进攻细节
     *
     * @param attackUnion 攻击联盟
     * @param attackId    攻击玩家id
     * @param defendUnion 防守联盟
     * @param sonType
     * @param durable
     * @param time
     */
    public void addBattleDetail(SeacraftSouthSeaUnionInfo attackUnion, long attackId, SeacraftSouthSeaUnionInfo defendUnion, int sonType, int durable, long time) {
        attackUnion.addBattleDetail(0, sonType, defendUnion.getUnionData().getUnionId(), attackId, durable, time);
        defendUnion.addBattleDetail(1, sonType, attackUnion.getUnionData().getUnionId(), attackId, durable, time);
    }


    /**
     * 获取本轮的距离
     *
     * @return
     */
    protected long getRoundDistance() {
        CrossActivityDetail crossActivityDetail = ActivityMgr.getCrossActivityDetail(activityId, groupId,true);
        long distance = Long.MAX_VALUE;
        int round = (int) (crossActivityDetail.getParam1());
        SeacraftSouthSeaActivityConfig activityConfig = SeacraftSouthSeaConfigMgr.getConfigMap().get(activityId);
        if (activityConfig != null && activityConfig.roundTimeList.size() >= round) {
            Integer[] openTime = activityConfig.roundTimeList.get(round - 1);
            if (openTime != null) {
                distance = activityConfig.getSEACRAFT_CRAFT_DISTANCE() * ((openTime[1] - openTime[0]) / DateHelper.HOUR_SECONDS);
            }
        }
        return distance;
    }

    protected int getUnionRank(SeacraftSouthSeaUnionInfo unionInfo, boolean refreshUnionRank) {
        if (refreshUnionRank) {
            refreshUnionRank();
        }
        return rankList.indexOf(unionInfo) + 1;
    }


    public int getGroupId() {
        return groupId;
    }
}
